Bash: Was tun, wenn sich ein Prozess mit Strg+C nicht beenden lässt, weil das Bash-Skript eine Schleife enthält, die einen anderen Prozess aufruft? Gibt es eine bessere Lösung für den Ein-/Ausschalter?

Bash: Was tun, wenn sich ein Prozess mit Strg+C nicht beenden lässt, weil das Bash-Skript eine Schleife enthält, die einen anderen Prozess aufruft? Gibt es eine bessere Lösung für den Ein-/Ausschalter?

Der vollständige Titel dieser Frage lautet:

Bash: Was tun, wenn sich ein Prozess mit Strg+C nicht beenden lässt, weil das Bash-Skript eine Schleife enthält, die einen anderen Prozess aufruft? Gibt es eine bessere Lösung für den Ein-/Ausschalter?

Der Titel dieser Frage ist ziemlich selbsterklärend, aber hier sind einige detailliertere Informationen:

Ich habe ein Bash-Skript ausgeführt, das ein anderes Programm aufruft. (Führt ein anderes Programm aus.)

Dieses Programm ist ein Daten-/Kurvenanpassungsprogramm, das nicht mit unterbrochen werden kann CTRL-C. Aber nach dem Lesen diesesPost, ich habe herausgefunden, dass ich es töten kann mitCTRL-\

Hypothetische Gedanken …

Es ist also möglich, einfach auf der Tastatur herumzuhämmern, die STRG-Taste gedrückt zu halten und die \Taste zu drücken.ABERWas wäre, wenn Sie gestern eine wirklich teure mechanische Tastatur gekauft haben und nicht genug Geld haben, um eine andere billige Tastatur zu kaufen, auf der Sie herumhämmern möchten (weil Sie nicht die 10^6 Tastenanschläge verbrauchen möchten, die Sie haben, bevor Ihre glänzende neue mechanische Tastatur abgenutzt ist), oder alternativ nicht genug Zeit haben, Ihre alte Tastatur in Ihrem Haus zu finden, weil Ihr Haus entwederäußerstUnordnung (Chaos) herrscht oder weil gleichzeitig ein Notfall wie beispielsweise ein Frittierpfannenbrand eintritt ...

Bedenken Sie auch, dass dieses Anpassungsprogramm durch eine Schleife aufgerufen wird und Sie möglicherweise 1.000 Datendateien anpassen. Das \1.000-malige Drücken der Taste wird wahrscheinlich lange dauern.

Gedanken zum Hyperraum …

Oder sogar: Was wäre, wenn Sie im Bash-Skript einen Fehler gemacht hätten und es tatsächlich eine Endlosschleife ausführt?

Was können Sie tun, um die Ausführung des übergeordneten Skripts in dieser Situation zu stoppen? Sie könnten Ihren Computer vom Strom trennen, den Netzschalter 10 Sekunden lang gedrückt halten, um ihn auszuschalten, oder ihn ins Frittierpfannenfeuer werfen, um ihn zum Abschalten zu bringen, aber diese Lösungen erscheinen aufgrund des möglichen Datenverlusts, der auftreten kann, unsinnig.

Theoretisch könnte man den Systemmonitor ausführen und vielleicht den Bash-Prozess beenden, aber dieser kann schwer zu finden sein, wenn Sie viele solcher Prozesse mit demselben Namen haben ... Außerdem haben Sie vielleicht einen Single-Core-Computer oder einen Multi-Core-Computer mit beispielsweise N Kernen, auf dem N Prozesse laufen, die alle versuchen, 100 % der CPU zu nutzen. Oder vielleicht nutzt nur ein Prozess mehr als die 4 GB RAM, die Sie haben, und deshalb ist Ihr Computer aus diesem Grund extrem langsam ... Zumindest zu langsam, um den Systemmonitor im Moment auszuführen. Die nächstbeste Option danach ist, STRG-ALT-F1 zu drücken und zu versuchen, sich als Root anzumelden und ps -Adann den fehlerhaften Bash-Elternprozess zu finden kill PID... Aber auch dies kann viele Minuten Ihrer Zeit in Anspruch nehmen, wenn Ihr Computer so stark ausgelastet ist, dass er ständig in den Swap schreibt.

SIG TERM exec cpu_broken.sh; wieder zusammenkommen; Bildschirm löschen; Denkprozesse löschen; fortfahren …

Gibt es eine bessere Lösung?

Antwort1

Sie führen also im Grunde ein Skript aus, das alles unzugänglich macht, und Sie möchten eine schnelle und einfache Lösung, um es zu stoppen. Eine Alternative zum Powercycling besteht darin, SYSRQdie Taste gedrückt zu halten (in vielen Fällen ist dies dasselbe wie PRTSCdie Taste ) und nacheinander R, E, I, S, , U, zu drücken B. Im Grunde ist dies eine sichere Möglichkeit, alle laufenden Prozesse zu beenden und das System neu zu starten.

Alternativ dazu können Sie auch sudo nano /proc/sysrq-triggerb in die Datei schreiben und speichern. Das System wird sofort neu gestartet.

Mehr Info: https://en.wikipedia.org/wiki/Magic_SysRq_key

Antwort2

Sie müssen die gesamte Prozessgruppe beenden. Die Prozessgruppen-ID (PGID) ist die PID des Prozesses, der die Gruppe gestartet hat. Um die Prozessgruppe zu beenden, müssen Sie die PID des Prozesses finden, der die Prozessgruppe gestartet hat, also das Skript oder den Befehl, der alles gestartet hat. Die Syntax lautet:

kill -- -PGID

Zum Beispiel:

kill -- -1234

Hier ist 1234 die PGID (Process Group ID).

Dadurch wird SIGTERM an alle Prozesse in der Prozessgruppe gesendet. Um ein anderes Signal zu senden, z. B. SIGKILL (9), gehen Sie wie folgt vor:

kill -9 -1234

So finden Sie die PGID:

Du kannst tun:

ps -eo 'pid,ppid,pgid,cmd'

Hier werden die PID, PPID (Parent Process ID), PGID und der Prozessname angezeigt.

Jetzt können Sie grepoder eine andere geeignete Methode verwenden, um die PGID zu finden und sie dann mit den oben genannten Methoden zu löschen.

Der Grund, warum ich den Befehl zum Anzeigen der PPID erstellt habe, liegt darin, dass Sie auch versuchen können, den Prozess basierend auf der PPID-Übereinstimmung folgendermaßen zu beenden pkill:

pkill -P PPID

Zum Beispiel:

pkill -P 6789

Bei dieser Methode müssen Sie alle übergeordneten (und untergeordneten) Prozesse finden und diese dann beenden. Wenn Sie also alle Prozesse beenden möchten, ist es meiner Meinung nach besser, den gesamten Prozessbaum zu beenden.

Antwort3

Normalerweise können Sie top, htopoder ähnliches verwenden, um den Prozess zu finden und zu beenden (oder wenn Sie den Namen oder die PID des Prozesses kennen, können Sie killall, pkillusw.). Beispielsweise kann ich mit ein vom Terminal ausgeführtes Skript auswählen und es durch Drücken von + topbeenden :kEnter

Bildbeschreibung hier eingeben

Wenn das nicht funktioniert, k+ 9+ Entersollten Sie das Signal SIGKILL verwenden. SIGKILL fordert, dass der Prozess sofort beendet wird, und wartet nicht, bis der Prozess mit dem Bereinigen von Ressourcen usw. fertig ist, wie dies bei SIGTERM der Fall ist. Ctrl+ CEin Prozess sendet SIGINT nur, um den Prozess zu unterbrechen, wie dies bei SIGTERM der Fall ist.

Mithilfe der Strukturansicht (drücken Sie t) in htop können Sie außerdem die übergeordneten Prozesse eines Skripts ermitteln und diese beenden, um sicherzustellen, dass es nicht in einer Endlosschleife endet.

Siehe auch:

verwandte Informationen