2010-02-18 3 views
7

Warten wartet nicht darauf, dass alle untergeordneten Prozesse gestoppt werden. Das ist mein Skript:Den Linux-Befehl "Wait" warten auf ALLE untergeordneten Prozesse warten

#!/bin/bash 

titlename=`echo "[email protected]"|sed 's/\..\{3\}$//'` 
screen -X title "$titlename" 

/usr/lib/process.bash -verbose [email protected] 

wait 

bash -c "mail.bash [email protected]" 
screen -X title "$titlename.Done" 

Ich habe keinen Zugriff auf /usr/lib/process.bash, aber es ist ein Skript, das sich häufig ändert, so möchte ich es verweisen ... aber in diesem Skript:

#!/bin/ksh 
#lots of random stuff 
/usr/lib/runall $path $auto $params > /dev/null 2>&1& 

Mein Problem ist, dass runall eine Protokolldatei erstellt ... und mail.bash wird angenommen, mir diese Protokolldatei auf der Post, aber das warten wartet nicht auf runall zu beenden, scheint es nur zu sein warten auf process.bash zu beenden. Gibt es überhaupt, ohne Zugriff auf process.bash, oder versuchen, meine eigene aktuelle Version von process.bash zu halten, um die Wartezeit richtig warten auf runall zu beenden? (Die Protokolldatei überschreibt den vorherigen Lauf, so kann ich auf das Vorhandensein der Protokolldatei nicht nur überprüfen, da es immer ist man da)

Danke, Dan

+0

Können Sie uns mit den entsprechenden Teilen von 'ps -ef 'nach' warten' ist beendet? Das sollte zeigen, welche Prozesse ausgeführt werden und welcher Prozess ein Kind von welchem ​​anderen Prozess ist ... – Heinzi

+0

Mein Skript und Process.bash enden fast sofort. Der einzige verbleibende Prozess ist Runall, der unter zufälligen PIDs läuft. – Dan

Antwort

9
(
    . /usr/lib/process.bash -verbose [email protected] 
    wait 
) 

Statt lassen die OS process.bash starten, schafft dies eine Sub-Shell, führt alle Befehle in process.bash als wenn sie in unser Shell-Skript eingegeben wurden und innerhalb dieser Subshell warten.

Es gibt einige Vorbehalte, aber es sollte funktionieren, wenn Sie nichts Ungewöhnliches tun.

+0

Wow ...also dann runall weil ein unterprozess meines scriptes? Das funktionierte wie ein Zauber (ich musste mein Skript in ksh ändern, um es mit process.bash abzugleichen). Strg + C stoppt nur die Wartezeit anstelle von runall ... Im Idealfall würde ich process.bash einfach ohne das "&" ausführen können, aber ich kann diesen Code nicht ändern und möchte nicht ständig aktualisieren Mein Code jedes Mal process.bash ändert sich. Vielen Dank. – Dan

+3

Um Strg-C zu haben, töten Sie den Hintergrundprozess, verwenden Sie falle und kill: 'pid = $ !; falle "kill $ pid; warte $ pid; beende 0" SIGINT SIGTERM; warte $ pid' –

4

wait nur für direkte Kinder wartet; Wenn Kinder ihre eigenen Kinder spawnen, wird es nicht auf sie warten.

+0

Gibt es das überhaupt? Wenn ich will, dass es direkt und indirekt auf alle Kinder wartet? – Dan

+1

Die einzige andere Möglichkeit besteht darin, nach PID oder Jobspec zu warten. –

2

Das Hauptproblem ist, dass, weil process.bash hat verlassen runall Prozess wird verwaist und im Besitz von init (PID 1). Wenn Sie sich die Prozessliste ansehen, wird runall keine sichtbare Verbindung zu Ihrem Prozess mehr haben, da das intermediate process.bash Skript beendet wurde. Es gibt keine Möglichkeit, oder etwas Ähnliches zu verwenden, um nach diesem "Enkelkind" -Prozess zu suchen, sobald er verwaist ist.

Sie können wait auf eine bestimmte PID. Kennen Sie die PID des Prozesses runall? Wenn es nur einen solchen Prozess ist Sie dies versuchen könnte, die für alle laufenden runall s warten:

wait `pidof runall` 
+0

Dies funktioniert nicht, da der Runall kein Kind des ursprünglichen Skripts ist. – abhaga

1

Sie könnten die PID des Prozesses erholen, für die Sie

warten wollen und dann diese PID als Argument übergeben auf den Befehl warten