Van egy olyan parancsom, amelyet minden alkalommal, amikor leáll, szeretnék automatikusan futtatni, ezért valami hasonlót futtattam:
while [ 1 ]; do COMMAND; done;
de ha nem tudom leállítani a ciklust a Ctrl-c gombbal, mivel az csak megöli COMMAND
és nem a teljes ciklus.
Hogyan érhetnék el valami hasonlót, de amit le tudok állítani anélkül, hogy be kellene zárnom a terminált?
Megjegyzések
- Ha ‘ m a bash-ban, akkor a Ctrl-Z billentyűkombinációval állítom le a munkát, majd div id = “8afb4ea65f”>
hogy megölje.
Válasz
Ellenőrizze a parancs kilépési állapotát. Ha a parancsot jelzéssel fejezték be, a kilépési kód 128 + a jel száma lesz. A GNU online dokumentációja a bash számára:
A shell céljaira egy parancs amely kilép a nulla kilépési státusszal, sikerült. A nullától eltérő kilépési állapot hibát jelez. Ezt a látszólag ellentétes sémát alkalmazzák, így van egy jól körülhatárolható módszer a siker jelzésére, és sokféle módon lehet jelezni a különféle hibamódokat. Amikor egy parancs véget vet egy N jelű fatális jelnek, Bash a 128 + N értéket használja kilépési állapotként.
A POSIX azt is megadja , hogy a jel által végződött parancs értéke nagyobb, mint 128, de úgy tűnik, hogy nem adja meg annak pontos értékét, mint a GNU:
Egy olyan parancs kilépési állapotát, amely azért szűnt meg, mert jelet kapott, nagyobbnak kell jelenteni, mint 128.
Ha például megszakít egy parancsot a C-vezérlővel, a kilépési kód 130 lesz, mert a SIGINT a 2. jel a Unix rendszereken. Tehát:
while [ 1 ]; do COMMAND; test $? -gt 128 && break; done
megjegyzések
Válasz
A ctrl + z használatával leállíthatja és háttérbe helyezheti a munkáját, miközben fut. megöli a munkáját a következővel:
$ kill %1
Ahol [1] a munkája száma.
Megjegyzések
- Lásd még ezt a választ a magyarázatokért és egyebekért.
- Ez a viszonylag friss válasz egyszerűen működik. Meg kell szavazott. +1
- Nagyon sokat segítettél nekem. Ezt kerestem ebben a kérdésben 🙂
Válasz
Azt mondanám, hogy az lenne a legjobb, ha a végtelen ciklusát egy szkriptbe tennénk, és ott kezelnénk a jeleket. Biztos vagyok benne, hogy módosítani akarja, hogy megfeleljen. A szkript a trap
segítségével elkapja a ctrl – c (vagy a SIGTERM
) fájlokat, megöli a parancsot (sleep
-t használtam tesztként) és kilép.
cleanup () { kill -s SIGTERM $! exit 0 } trap cleanup SIGINT SIGTERM while [ 1 ] do sleep 60 & wait $! done
Megjegyzések
- Szép. Itt ‘ s hogyan használtam ezt a tippet egy automatikus újraindítású netcat csomagoló készítéséhez:
trap "exit 0" SIGINT SIGTERM; while true; do netcat -l -p 3000; done
- ha ezt a
trap
megközelítést hozzáadja ugyanahhoz a (bash) szkripthez, a megölendő végtelen hurkot használva, használja a$$
$!
helyett (lásd itt )
Válasz
Általában csak lenyomva tartom a Ctrl-C gombot. Előbb vagy utóbb “regisztrál a ” s így megszakítja a while
ciklust. Talán van ennél jobb módszer is.
Megjegyzések
- Nem tudom, miért, de nem sikerül bizonyos COMMAND-oknál, például
paplay
egy 1-es fájlnál . - Nekem bevált
- Ez ‘ az itteni megoldások nyers erejét. : /
Válasz
Ha a bash-t futtatja a -e
minden hiba esetén kilép:
#!/bin/bash -e false # returns 1 echo This won"t be printed
Megjegyzések
- Az első sor itt messze van a legegyszerűbb megoldás egy triviális szkriptre, amelyre nem kíván ‘ túl sok időt tölteni!
Válasz
Miért nem egyszerűen,
while [ 1 ]; do COMMAND || break; done;
Vagy ha szkriptben használják,
#!/bin/bash while [ 1 ]; do # ctrl+c terminates COMMAND and exits the while loop # (assuming COMMAND responds to ctrl+c) COMMAND || break done;
Megjegyzések
- Nagyon elegáns megoldás. De vajon ‘ ez csak akkor működne, ha a COMMAND mindig sikeres kilépési állapotot adna vissza?
- Igen @howardh, hogy ‘ s helyesek.
Válasz
- Egy folyamatot mindig meg lehet ölni annak PID-jével, ott ” nincs szükség a terminál bezárására.
- Ha egy végtelen ciklusban szeretne futtatni valamit, mint egy démon, akkor a legjobban a háttérbe helyezheti
-
while :
végtelen ciklust hoz létre, és elmenti a[ 1 ]
while :; do COMMAND; done &
Ez kinyomtatja a PID-t. Ha kilép a parancssorból az ctrl+d
használatával, a háttérmunka nem zárul le, és később bárhonnan megölheti a munkát a kill PID
Ha elvesztette a PID azonosítóját, a pstree -pa $USER
vagy a pgrep -fl ".*PROCESS.*"
használatával megkeresheti
Válasz
Egy másik megoldást preferálok:
touch .runcmd; while [ -f ".runcmd" ]; do COMMAND; sleep 1; done
Sorrendben a hurok elpusztításához tedd:
rm .runcmd && kill `pidof COMMAND`
Válasz
Mi működik ésszerűen nekem jó:
while sleep 1; do COMMAND; done
Ez azért működik, mert az 1. alvás egy míg és ha a ctrl + c értéket kapja, akkor nem nullával tér vissza, és a hurok véget ér.
Megjegyzések
- +1, az alvási idő is megadható
0.5
vagy0.1
-re redukálva:while sleep 0.1; do COMMAND; done
Válasz
A trap
használata –
exit_() { exit } while true do echo "running.." trap exit_ int done
paplay alert.ogg
, talán azért, mert apaplay
kezeli a jelet?