Bash-Snippet, um einen Prozess zu beenden, bis er tot ist?

8

Ich versuche, ein robustes Bash-Skript zu schreiben, und darin erstelle ich einen Hintergrundprozess. Am Ende des Skripts möchte ich es töten. Ich habe es PID.

Ich dachte an so etwas

while [[ ps ef $PID ]] ; do
  kill $PID
  sleep 0.5
done

Irgendwelche Vorschläge für etwas Besseres? Mögliche Probleme mit diesem Ansatz?

Rory
quelle
Meinten Sie nicht ps -ef?
user1686
1
Grawity: Das ist nur BSD-Stil gegen UNIX-Optionen, aber ef scheint besser zu den UNIX-Optionen zu passen. Ich würde mit 'ps ao pid' selbst gehen
Kyle Brandt
while [[ ps ef $PID ]]ist ein Syntaxfehler. Ich nehme an, du meintest while ps ef $PID.
Dennis

Antworten:

10

Das Problem beim wiederholten Beenden eines Prozesses besteht darin, dass Sie eine Race-Bedingung für die Erstellung neuer Prozesse haben. Es ist nicht besonders wahrscheinlich, aber es ist möglich, dass der Prozess beendet wird und ein neuer Prozess mit derselben PID gestartet wird, während Sie schlafen.

Warum müssen Sie den Prozess wiederholt abbrechen? Wenn der Prozess beendet wird, das Beenden nach dem Empfang des Signals jedoch einige Zeit dauern kann, können Sie Folgendes verwenden wait:

 kill $PID
 wait $PID

In einem idealen System müssten Sie niemals ein killoder ein Problem wiederholen kill -9 $PID. Wenn Sie müssen, sollten Sie in Betracht ziehen, das zu reparieren, was gerade ausgeführt wird, damit Sie es nicht müssen. In der Zwischenzeit werden Sie wahrscheinlich die Rennbedingung nicht erreichen, und Sie können sich dagegen schützen, indem Sie (sagen wir) den Zeitstempel von / proc / $ PID / überprüfen, bevor Sie den Prozess beenden. Das ist allerdings eine schlechte Hackiness.

Andrew Aylett
quelle
1
Dies funktioniert nicht, wenn die PID nicht zu einem untergeordneten Prozess gehört, dh dieses Skript versucht, die Ausführung eines Prozesses zu steuern, der von einem anderen Ort stammt. Ich bekomme, bash: wait: pid 32137 is not a child of this shellwenn ich es versuche. :(
Justin Force
9

Für alle, die den Schritt von kill $PIDbis empfehlen kill -9 $PID, muss ich Sie an die nutzlose Verwendung von kill -9 erinnern .

Nein nein Nein. Verwenden Sie nicht kill -9.

Es gibt dem Prozess keine Chance, sauber:

  1. Socket-Verbindungen herunterfahren

  2. Bereinigen Sie temporäre Dateien

  3. Informieren Sie seine Kinder, dass es weggeht

  4. Setzen Sie die Klemmeneigenschaften zurück

und so weiter und so weiter und so fort.

Senden Sie im Allgemeinen 15 und warten Sie ein oder zwei Sekunden. Wenn dies nicht funktioniert, senden Sie 2, und wenn dies nicht funktioniert, senden Sie 1. Wenn dies nicht funktioniert, entfernen Sie die Binärdatei, da sich das Programm schlecht verhält!

Verwenden Sie nicht kill -9. Nehmen Sie den Mähdrescher nicht heraus, nur um den Blumentopf aufzuräumen.

Jetzt stimme ich dem "Entfernen des binären Teils" nicht zu, aber der Fortschritt scheint weniger schädlich als nur ein kill -9.

Ich stimme auch der Sorgfalt bezüglich der Rennbedingungen bei der Schaffung neuer Prozesse mit derselben hier erwähnten PID zu .

Adriano Varoli Piazza
quelle
0

Mach zuerst deinen normalen Kill, schlafe x Anzahl von Sekunden und töte ihn dann -9, wenn er noch da ist. Dies scheint auch eine seltsame Situation zu sein, in die Sie geraten sind. Vielleicht möchten Sie uns das größere Problem erklären.

Kyle Brandt
quelle
Einverstanden. Wenn es nach einem SIGTERM nicht reagiert und schließt (das standardmäßig per Kill gesendete Signal), reagiert es wahrscheinlich nicht auf ein 2., 3., 4., ...., also sollte Ihre nächste Vorgehensweise SIGKILL sein (kill - 9). Natürlich sollten Sie sicherstellen, dass das X in "Schlaf-X-Sekunden" lang genug ist, damit der Prozess einen normalen Clear-Your-Desk-and-Leave-Vorgang ausführen kann, selbst wenn das System stark ausgelastet ist - dies kann einen Bruchteil von dauern eine Sekunde normalerweise, aber einige zehn Sekunden, wenn das System schlägt.
David Spillett
0

Normalerweise möchten Sie es kill $PIDzuerst versuchen .

Lassen Sie es dann ein wenig schlafen, um zu sehen, ob es ordnungsgemäß beendet wird.

Wenn nicht, dann ausführen, kill -9 $PIDum es gewaltsam loszuwerden.

Brent
quelle
-1

warum nicht einfach

kill -9 $PID

chris
quelle
2
Weil Sie Prozessen die Möglichkeit geben möchten, sauber aufzuräumen und zu sterben, was das TERM-Signal tut (das Standardsignal). Das KILL-Signal ("-9") gibt Prozessen diese Chance nicht.
Turm
Guter Punkt, aber das Originalplakat sagte, er wollte es nur töten.
Chris