Wie kann ich einen Prozess im Hintergrund starten und prüfen, wann er in einem Bash-Skript endet? Meine Idee ist ein Skript wie dieses:
launch backgroundprocess & while [ Process is running ];do echo "PROCESS IS RUNNING\r" done; echo "PROCESS TERMINATED"
Antwort
Der Schlüssel ist den Befehl „wait“:
#!/bin/bash /my/process & /another/process & wait echo "All processes done!"
Kommentare
- Vorteil: Die CPU wird NICHT gebrannt Zeit mit einer Endlosschleife, die ständig läuft ….;)
- Der Nachteil dabei ist, dass Sie ' nichts anderes tun können, während Sie warten B. dem Benutzer den Fortschritt anzeigen. Dies können Sie nur mit der Lösung cuonglm ' .
- @Mark Booth Sie können Zeigen Sie den Fortschritt mit einem dritten asynchronen Job an. Beispiel:
cmd1 & p=$!; cmd2 & q=$!; while sleep 1; do echo still running ; done& wait $p $q; kill $!;
Antwort
Mit wait
Sie können die Granularität haben, die Sie benötigen:
sleep 1 & PID1=$! sleep 2 & PID2=$! wait $PID1 echo "PID1 has ended." wait echo "All background processes have exited."
Antwort
Hier ist eine Möglichkeit, dies zu tun:
launch backgroundprocess & PROC_ID=$! while kill -0 "$PROC_ID" >/dev/null 2>&1; do echo "PROCESS IS RUNNING" done echo "PROCESS TERMINATED" exit 0
Kommentare
- Danke, Dies ist definitiv die einzige Antwort, die meine Interpretation der ursprünglichen Frage beantwortet (und der Grund, warum ich mir diese Frage angesehen habe).
- @cuonglm, Was gibt es für mehrere Prozesse? Wahrscheinlich ist
wait
besser dafür geeignet? - @cuonglm Was bewirkt die Option -0 zum Beenden des Befehls
- @k_vishwanath, ob es einen Prozess gibt wird noch ausgeführt oder nicht.
Antwort
Sie können Ihren Prozess mit nohup ausführen und ein Shell-Skript zum Lesen schreiben nohup.out-Datei, die nohup zum Protokollieren verwendet.
nohup command &
Kommentare
- (1) Bei der Risiko, Haare zu spalten,
nohup
schreibt ' nichts annohup.out
; Es erstellt lediglich die Datei und erstellt die Ausgabe des Befehls an diese weiter. (2) Wenn der Befehl ' keine Ausgabe erzeugt, wird nichts innohup.out
geschrieben, und diese Idee geht nirgendwo schnell. (3) Auch wenncommand
eine Ausgabe schreibt, wie können Sie feststellen, wann diese endet, indem Sie diese Ausgabe überwachen? - @ G- Man kann vielleicht durch Überprüfen der Ausgabe von
lsof
feststellen, obnohup
nochnohup.out
verwendet. Ich stimme jedoch zu, dass dies eine sehr haarige Methode ist. - (4) Wenn
command
ausgeführt wird,nohup
ist weg. (1) Ja, ich wiederhole eine Zahl, weil ich wiederhole, was ich vor zwei Jahren gesagt habe:nohup
schreibt nichts annohup.out
. (5) Ja, Sie können ein Shell-Skript schreiben, umlsof
zu schleifen und auszuführen, um festzustellen, obnohup.out
noch geöffnet ist. Aber das wäre eine andere Antwort. (6) Selbst wenn Sie das tun würden, wäre es unzuverlässig. Was ist, wenn ein anderer Prozess die Dateinohup.out
geöffnet hat? Sie möchten wirklich überprüfen, ob für diesen bestimmten Prozessnohup.out
geöffnet war. (7) Aber wenn Sie das tun, warum nicht einfach prüfen, ob der Prozess ausgeführt wird?
Antwort
wait
funktioniert nur für einen untergeordneten Prozess, der in derselben Shell gestartet wird. es ist schließlich eine Shell-Funktion.
Für jeden beliebigen Hintergrundprozess müssen Sie mit PID arbeiten. Was hier niemand erwähnt, ist das Kernel-PID-Recycling . Moderne Linux-Systeme können PID durchaus wiederverwenden häufig abhängig von der Last. Sie benötigen mehr als nur PID, um den Prozess zuverlässig zu identifizieren. Ein einfacher Ansatz besteht darin, Zeit zu sparen Wenn der Prozess gestartet wurde, vergleichen Sie ihn regelmäßig mit der aktuellen Prozessstartzeit. Sollte die PID recycelt werden, ist ihre Startzeit nicht dieselbe.
Die Prozessstartzeit wird als Feld 22 in / proc / [pid] / stat -Datei. Die Zeit wird in jiffies (höchstens 10 ms) gemessen, was ausreichend ist Genauigkeit beim Erkennen des Recycling von Prozess-IDs.
PID=<process ID> START_TIME=$(cut -d " " -f 22 /proc/$PID/stat) while [ "$(cut -d " " -f 22 /proc/$PID/stat 2>/dev/null)" = "$START_TIME" ]; do echo "PROCESS IS RUNNING" sleep 1 done