Geben Sie weitere Details an. Möchten Sie es interaktiv oder programmgesteuert stoppen?
Manatwork
1
Sie können drücken ctrl-c, um das SIGINTSignal zu senden (in den meisten Shells), oder Sie können drücken ctrl-z, um das Signal zu senden (in den SIGTSTPmeisten Shells). In dem Fall, dass Sie gedrückt haben, wird ctrl-zder zugehörige Prozess nicht abgebrochen, sondern angehalten. Sie können es mit fg(mindestens in bash)
user1146332
Nein, das geht nicht!
Yinyanghu
4
Das Problem ist nicht das Skript, sondern der slBefehl, den ich für ärgerlich halte, wenn man falsch schreibt lsund einen Zug zeigt, der langsam vorbeifährt. Soweit ich weiß, fängt es das SIGINTSignal ab und muss mit getötet werden SIGKILL.
1
Vielen Dank. Nicht für meine Distribution gepackt, deshalb habe ich es nicht gewusst / gefunden. (Ich glaube, ich werde keinen Antrag dafür stellen.)
manatwork
Antworten:
64
Das Programm slignoriert absichtlich SIGINT, was gesendet wird, wenn Sie drücken Ctrl+C. Zunächst müssen Sie also durch Hinzufügen des Arguments angeben, dass Sie slnicht ignorieren sollen .SIGINT-e
Wenn Sie dies versuchen, werden Sie feststellen, dass Sie jeden einzelnen stoppen können sl, aber sie wiederholen sich immer noch. Sie müssen sagen bash, dass Sie auch nach beenden müssen SIGINT. Sie können dies tun, indem Sie ein trap "exit" INTvor die Schleife setzen.
Ich habe es nicht installiert, um zu überprüfen, aber Sie können es möglicherweise auch mit SIGQUIT von Ctrl- \
derobert
120
Drücken Sie Ctrl-Z, um das Skript anzuhalten
kill %%
Das %%teilt der integrierten Bash mit, killdass Sie ein Signal (standardmäßig SIGTERM) an den zuletzt angehaltenen Hintergrundjob in der aktuellen Shell und nicht an eine Prozess-ID senden möchten.
Sie können Jobs auch nach Nummer oder nach Name angeben. Wenn Sie z. B. einen Job mit ^ Z anhalten, werden Sie von bash über die Jobnummer informiert [n]+ Stopped, wobei nin den eckigen Klammern die Jobnummer steht.
Für weitere Informationen über Auftragssteuerung und zu töten , Jobs, laufen help jobs, help fg, help bg, und help killin bash, und die Suche nach JOB CONTROL(alle Caps) oder jobspecin der bash man - Seite.
z.B
$ ./killme.sh
./killme.sh: Zeile 4: sl: Befehl nicht gefunden
./killme.sh: Zeile 4: sl: Befehl nicht gefunden
./killme.sh: Zeile 4: sl: Befehl nicht gefunden
./killme.sh: Zeile 4: sl: Befehl nicht gefunden
./killme.sh: Zeile 4: sl: Befehl nicht gefunden
...
...
...
./killme.sh: Zeile 4: sl: Befehl nicht gefunden
^ Z
[1] + Gestoppt ./killme.sh
$ kill %%
$
[1] + Beendet ./killme.sh
In diesem Beispiel war die Jobnummer 1, kill %1hätte also genauso funktioniert wiekill %%
(ANMERKUNG: Ich habe nicht slinstalliert, so dass die Ausgabe nur "Befehl nicht gefunden" ist. In Ihrem Fall erhalten Sie die Ausgabe, die sl erzeugt. Es ist nicht wichtig - das ^ZAnhalten und kill %%wird genauso funktionieren.)
Übrigens, um solche Schleifen schnell auszuführen, kann ^ Z eine zuverlässigere Methode sein, um den Prozess abzubrechen als ^ C. ^ C wird an das Programm ( sl) gesendet, das in der Schleife ausgeführt wird, aber das Skript läuft weiter ... und startet ein anderes sl. Wenn Sie ^ C einige Male sehr schnell drücken, können Sie möglicherweise sowohl sldas Skript als auch das Skript beenden (wenn keines von beiden SIGINT abfängt). ^ Z unterbricht das Skript fast sofort (sofort, wenn Sie keine gepufferten Ausgaben zählen, die noch auf Ihrem Terminal gedruckt werden), sodass Sie es mitkill %%
cas
Genau! Ich muss sagen " slist ein lustiges Programm". Diesmal macht es mir wieder Spaß! @ _ @
Yinyanghu
Nur eine Antwort, die auch zu funktionieren scheint, wenn die Schleife nicht von einem Skript, sondern direkt von der Kommandozeile aufgerufen wird.
Skippy le Grand Gourou
1
@DrewChapin Ich kann mich nicht erinnern, wann / wo ich davon erfahren habe - nur etwas, das ich "seit Ewigkeiten" kenne. Die Bash-Manpage (Suche nach Jobspec ) sagt:The symbols %% and %+ refer to the shell's notion of the current job, which is the last job stopped while it was in the foreground or started in the background. The previous job may be referenced using %-. If there is only a single job, %+ and %- can both be used to refer to that job
cas
6
Wenn Sie möchten, dass Strg + C die Schleife stoppt, das Skript jedoch nicht beendet, können Sie || breaknach jedem Befehl, den Sie ausführen, einen Befehl einfügen . Solange das von Ihnen ausgeführte Programm mit Strg + C beendet wird, funktioniert dies hervorragend.
#!/bin/bashwhile:do# ctrl+c terminates sl, but not the shell script
sl -e ||breakdone
Wenn Sie sich in einer verschachtelten Schleife befinden, können Sie "break 2" verwenden, um zwei Ebenen usw. zu verlassen.
Sie können dieses Skript beenden, indem Sie in dem Terminal, in dem Sie dieses Skript gestartet haben, Strg + C drücken. Natürlich muss dieses Skript im Vordergrund laufen, damit Sie es mit Strg + C stoppen können.
Oder Sie können die PID (Prozess-ID) dieses Skripts in einem anderen geöffneten Terminal finden, indem Sie:
Sie können killdie pidShell (Bash).
Ich habe es gerade versucht und es funktioniert.
Weil ich den Prozess von ps -ef(dem Job, den wir im Schleifenskript ausführen) nicht sehen kann.
Eine andere Möglichkeit, das gesamte Skript zu beenden, besteht darin, den slBefehl im Hintergrund auszuführen und dann das Signal abzufangen INT, um die gesamte Prozessgruppe des Skripts mit signal zu beenden HUP.
Warum wird Ihrer Meinung nach die PID des letzten Hintergrundbefehls jemals 0 sein?
Manatwork
-1
Das tödliche Ding ist schrecklich, weil man es jetzt nie tut, wenn das Skript zweimal ausgeführt werden muss. UND Ihr Beendigungscode ist falsch.
while[ something ];doif[ somethingelse ];then
echo shut down script with exit code 0
exit 0fidone
echo something else not happend
exit 2# Return val important for example for monitoring
Kein Arbeiten. Lösung = benutze Perl. während öffnet eigene Bash
ctrl-c
, um dasSIGINT
Signal zu senden (in den meisten Shells), oder Sie können drückenctrl-z
, um das Signal zu senden (in denSIGTSTP
meisten Shells). In dem Fall, dass Sie gedrückt haben, wirdctrl-z
der zugehörige Prozess nicht abgebrochen, sondern angehalten. Sie können es mitfg
(mindestens inbash
)sl
Befehl, den ich für ärgerlich halte, wenn man falsch schreibtls
und einen Zug zeigt, der langsam vorbeifährt. Soweit ich weiß, fängt es dasSIGINT
Signal ab und muss mit getötet werdenSIGKILL
.Antworten:
Das Programm
sl
ignoriert absichtlichSIGINT
, was gesendet wird, wenn Sie drücken Ctrl+C. Zunächst müssen Sie also durch Hinzufügen des Arguments angeben, dass Siesl
nicht ignorieren sollen .SIGINT
-e
Wenn Sie dies versuchen, werden Sie feststellen, dass Sie jeden einzelnen stoppen können
sl
, aber sie wiederholen sich immer noch. Sie müssen sagenbash
, dass Sie auch nach beenden müssenSIGINT
. Sie können dies tun, indem Sie eintrap "exit" INT
vor die Schleife setzen.quelle
Ctrl-Z
, um das Skript anzuhaltenkill %%
Das
%%
teilt der integrierten Bash mit,kill
dass Sie ein Signal (standardmäßig SIGTERM) an den zuletzt angehaltenen Hintergrundjob in der aktuellen Shell und nicht an eine Prozess-ID senden möchten.Sie können Jobs auch nach Nummer oder nach Name angeben. Wenn Sie z. B. einen Job mit ^ Z anhalten, werden Sie von bash über die Jobnummer informiert
[n]+ Stopped
, wobein
in den eckigen Klammern die Jobnummer steht.Für weitere Informationen über Auftragssteuerung und zu töten , Jobs, laufen
help jobs
,help fg
,help bg
, undhelp kill
in bash, und die Suche nachJOB CONTROL
(alle Caps) oderjobspec
in der bash man - Seite.z.B
In diesem Beispiel war die Jobnummer 1,
kill %1
hätte also genauso funktioniert wiekill %%
(ANMERKUNG: Ich habe nicht
sl
installiert, so dass die Ausgabe nur "Befehl nicht gefunden" ist. In Ihrem Fall erhalten Sie die Ausgabe, die sl erzeugt. Es ist nicht wichtig - das^Z
Anhalten undkill %%
wird genauso funktionieren.)quelle
sl
) gesendet, das in der Schleife ausgeführt wird, aber das Skript läuft weiter ... und startet ein anderessl
. Wenn Sie ^ C einige Male sehr schnell drücken, können Sie möglicherweise sowohlsl
das Skript als auch das Skript beenden (wenn keines von beiden SIGINT abfängt). ^ Z unterbricht das Skript fast sofort (sofort, wenn Sie keine gepufferten Ausgaben zählen, die noch auf Ihrem Terminal gedruckt werden), sodass Sie es mitkill %%
sl
ist ein lustiges Programm". Diesmal macht es mir wieder Spaß! @ _ @The symbols %% and %+ refer to the shell's notion of the current job, which is the last job stopped while it was in the foreground or started in the background. The previous job may be referenced using %-. If there is only a single job, %+ and %- can both be used to refer to that job
Wenn Sie möchten, dass Strg + C die Schleife stoppt, das Skript jedoch nicht beendet, können Sie
|| break
nach jedem Befehl, den Sie ausführen, einen Befehl einfügen . Solange das von Ihnen ausgeführte Programm mit Strg + C beendet wird, funktioniert dies hervorragend.Wenn Sie sich in einer verschachtelten Schleife befinden, können Sie "break 2" verwenden, um zwei Ebenen usw. zu verlassen.
quelle
Sie können dieses Skript beenden, indem Sie in dem Terminal, in dem Sie dieses Skript gestartet haben, Strg + C drücken. Natürlich muss dieses Skript im Vordergrund laufen, damit Sie es mit Strg + C stoppen können.
Oder Sie können die PID (Prozess-ID) dieses Skripts in einem anderen geöffneten Terminal finden, indem Sie:
Beide Wege sollten den Trick tun, nach dem Sie fragen.
quelle
Am einfachsten ist es, das
QUIT
Signal auszugeben, an das normalerweise angehängt wirdControl-Backslash
.Wenn Sie den Zug sehen, drücken Sie Strg- \
quelle
Sie können
kill
diepid
Shell (Bash).Ich habe es gerade versucht und es funktioniert.
Weil ich den Prozess von
ps -ef
(dem Job, den wir im Schleifenskript ausführen) nicht sehen kann.quelle
Eine andere Möglichkeit, das gesamte Skript zu beenden, besteht darin, den
sl
Befehl im Hintergrund auszuführen und dann das Signal abzufangenINT
, um die gesamte Prozessgruppe des Skripts mit signal zu beendenHUP
.quelle
Verwenden Sie
set -e
, um den Fehler zu beenden.quelle
sl
stirbt nicht mit ctrl + c.das sollte helfen.
quelle
Das tödliche Ding ist schrecklich, weil man es jetzt nie tut, wenn das Skript zweimal ausgeführt werden muss. UND Ihr Beendigungscode ist falsch.
Kein Arbeiten. Lösung = benutze Perl. während öffnet eigene Bash
quelle