Hur man använder timeout-kommandot på Linux

Okej, det räcker med datortid. Du kan ge processer tidsgränser och ställa in en maximal tid som de kan köras under med timeoutkommandot. Här är en handledning för att sätta gränser för att köra program med det här kommandot.

Vad gör timeout för dig?

Timeout-kommandot låter dig sätta en gräns för tidslängden ett program kommer att köras för. Men varför skulle du vilja göra det?

Ett fall är när du vet exakt hur länge du vill att en process ska pågå. Ett vanligt användningsfall är att ha timeout-kontroll av ett loggnings- eller datainsamlingsprogram så att loggfilerna inte obevekligt slukar ditt hårddiskutrymme.

Ett annat fall är när du inte vet hur länge du vill att en process ska pågå, men du vet att du inte vill att den ska pågå på obestämd tid. Du kanske har för vana att ställa in processer igång, minimera terminalfönstret och glömma dem.

Vissa program – även enkla verktyg – kan generera nätverkstrafik på nivåer som kan försämra ditt nätverks prestanda. Eller så kan de binda upp resurserna på en målenhet och sakta ner dess prestanda. (ping, jag tittar på dig.) Att låta den här typen av program köras under längre perioder medan du är borta från din dator är dålig praxis.

timeout är en del av GNU Core Utils så Linux och Unix-liknande operativsystem som macOS har alla timeout inbyggd. Det finns inget att installera; du kan använda den direkt ur lådan.

Komma igång Med timeout

Här är ett enkelt exempel. Till exempel, med dess förinställda kommandoradsalternativ, kommer ping-kommandot att köras tills du stoppar det genom att trycka på Ctrl+C. Om du inte avbryter det, kommer det bara att fortsätta.

ping 192.168.4.28

Genom att använda timeout kan vi se till att ping inte körs på och på, tugga upp nätverkets bandbredd och tjata vilken enhet som än pingas.

Detta nästa kommando använder timeout för att tidsbegränsa ping. Vi tillåter 15 sekunders körtid för ping.

timeout 15 ping 192.168.4.28

Efter 15 sekunders timeout avslutas pingsessionen och vi återgår till kommandoraden.

Använda timeout med andra tidsenheter

Observera att vi inte behövde lägga till ett ”s” bakom 15. timeout antar att värdet är i sekunder. Du kan lägga till ett ”s”, men det gör egentligen ingen skillnad.

För att använda ett tidsvärde mätt i minuter, timmar eller dagar lägg till ett ”m”, ett ”h” eller ett ”d”.

För att köra ping i tre minuter, använd följande kommando:

timeout 3m ping 192.168.4.28

ping kommer att köras i tre minuter innan timeout kliver in och stoppar pingsessionen.

Begränsar datainsamling med timeout

Vissa datafångstfiler kan växa sig stora mycket snabbt. För att förhindra att sådana filer blir svårhanterliga eller till och med problematiska i storlek, begränsa den tid som fångstprogrammet tillåts köra.

I det här exemplet använder vi tcpdump, en fånga nätverkstrafik verktyg. På testmaskinerna som denna artikel undersöktes på, var tcpdump redan installerat i Ubuntu Linux och Fedora Linux. Det måste installeras på Manjaro Linux och Arch Linux, med följande kommando:

sudo pacman -Syu tcpdump

Vi kan köra tcpdump i 10 sekunder med dess standardalternativ och omdirigera dess utdata till en fil som heter capture.txt med följande kommando:

timeout 10 sudo tcpdump > capture.txt

timeout 10 sudo tcpdump > capture.txt i ett terminalfönster” width=”646″ height=”77″ onload=”pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);”  onerror=”this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);”></p>
<p>(tcpdump har sina egna alternativ för att spara infångad nätverkstrafik till en fil. Detta är ett snabbt hack eftersom vi’ diskuterar timeout, inte tcpdump.)</p>
<p>tcpdump börjar fånga nätverkstrafik och vi väntar i 10 sekunder.  Och 10 sekunder kommer och går och tcpdump körs fortfarande, och capture.txt växer fortfarande i storlek.  Det kommer att ta en hastig Ctrl+C för att stoppa tcpdump.</p>
<p>Att kontrollera storleken på capture.txt med ls visar att den växte till 209K på några sekunder.  Den filen växte snabbt!</p>
<pre>ls -lh capture.txt</pre>
<p><img loading=

Vad hände? Varför stoppade inte timeout tcpdump?

Allt har med signaler att göra.

Skickar rätt signal

När timeout vill stoppa ett program skickar den SIGTERM-signal. Detta ber artigt att programmet avslutas. Vissa program kan välja att ignorera SIGTERM-signalen. När det händer måste vi säga att timeout ska vara lite mer kraftfull.

Vi kan göra det genom att be timeout för att skicka SIGKILL-signalen istället.

SIGKILL-signalen kan inte ”fångas, blockeras eller ignoreras” – den kommer alltid igenom. SIGKILL ber inte artigt att programmet ska sluta. SIGKILL gömmer sig runt hörnet med ett stoppur och en cosh.

Vi kan använda alternativet -s (signal) för att tala om timeout för att skicka SIGKILL-signalen.

timeout -s SIGKILL 10 sudo tcpdump > capture.txt

timeout -s SIGKILL 10 sudo tcpdump > capture.txt i ett terminalfönster” width=”646″ height=”167″ onload=”pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);”  onerror=”this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);”></p>
<p>Den här gången, så snart 10 sekunder har förflutit, stoppas tcpdump.</p>
<p>< img src=

Frågar artigt först

Vi kan be timeout för att försöka stoppa programmet med SIGTERM, och att bara skicka in SIGKILL om SIGTERM inte fungerade.

För att göra detta använder vi alternativet -k (döda efter). Alternativet -k kräver ett tidsvärde som parameter.

I det här kommandot ber vi timeout för att låta dmesg köras i 30 sekunder och sedan avsluta det med SIGTERM-signalen. Om dmesg fortfarande körs efter 40 sekunder betyder det att den diplomatiska SIGTERM ignorerades och timeout bör skickas in SIGKILL för att avsluta jobbet.

dmesg är ett verktyg som kan övervaka kärnringens buffertmeddelanden och visa dem i ett terminalfönster.

timeout -k 40 30 dmseg -w

dmesg körs i 30 sekunder och stannar när den tar emot SIGTERM-signalen.

Vi vet att det inte var SIGKILL som stoppade dmesg eftersom SIGKILL alltid lämnar en dödsannons med ett ord i terminalfönstret: ”Dödad.” Så skedde inte i det här fallet.

Hämta programmets utgångskod

Väluppfostrade program skickar ett värde tillbaka till skalet när de avslutas. Detta är känt som en utgångskod. Vanligtvis används detta för att tala om för skalet – eller vilken process som startade programmet – om problem uppstod av programmet när det kördes.

timeout ger sin egen utgångskod, men vi kanske inte bryr oss om det. Vi är förmodligen mer intresserade av exitkoden från processen som timeout styr.

Detta kommando låter ping köras i fem sekunder. Det plingar en dator som heter Nostromo, som finns på testnätverket som användes för att undersöka den här artikeln.

timeout 5 ping Nostromo.local

Kommandot körs i fem sekunder och timeout avslutar det. Vi kan sedan kontrollera utgångskoden med detta kommando:

echo $?

Exit-koden är 124. Detta är värdet som timeout använder för att indikera att programmet avslutades med SIGTERM. Om SIGKILL avslutar programmet är utgångskoden 137.

Om vi ​​avbryter programmet med Ctrl+C är utgångskoden från timeout noll.

timeout 5 ping Nostromo.local
echo $?

Om exekveringen av programmet avslutas innan timeout avslutar det, kan timeout skicka utgångskoden från programmet tillbaka till skalet.

För att detta ska hända måste programmet avstanna av sig själv (med andra ord, det avslutas inte med timeout), och vi måste använda alternativet –bevara-status.

Om vi ​​använder alternativet -c (count) med ett värde på fem kommer ping bara att avfyras fem förfrågningar. Om vi ​​ger timeout en varaktighet på en minut, kommer ping definitivt att ha avslutats av sig själv. Vi kan sedan kontrollera utgångsvärdet med hjälp av eko.

timeout --preserve-status 1m ping -c 5 Nostromo.local
echo $?

ping slutför sina fem ping-förfrågningar och avslutas. Utgångskoden är noll.

För att verifiera att utgångskoden kommer från ping, låt oss tvinga ping att generera en annan utgångskod. Om vi ​​försöker skicka ping-förfrågningar till en icke-existerande IP-adress, kommer ping att misslyckas med en utgångsfelkod. Vi kan sedan använda eko för att kontrollera att utgångskoden inte är noll.

timeout --preserve-status 1m ping -c 5 NotHere.local
echo $?

Ping-kommandot kan uppenbarligen inte nå den icke-existerande enheten, så det rapporterar felet och stängs. Utgångskoden är två. Detta är utgångskoden som ping använder för allmänna fel.

Att sätta grundregler

timeout handlar om att ge några gränser för program som körs. Om det finns en fara kan loggfilerna överskrida din hårddisk eller att du kanske glömmer att du lämnade ett nätverksverktyg igång, linda in dem i timeout och låt din dator självreglera sig.