2016-06-03 2 views
4

Gibt es irgendwelche eingebaute Funktion in Bash auf 1 von vielen Prozessen zu warten, um zu beenden? Und dann die verbleibenden Prozesse töten?Warten auf "1 von vielen Prozess" zu beenden

pids="" 
# Run five concurrent processes 
for i in {1..5}; do 
     (longprocess) & 
     # store PID of process 
     pids+=" $!" 
done 

if [ "one of them finished" ]; then 
     kill_rest_of_them; 
fi 

Ich bin auf der Suche nach "einer von ihnen fertig" Befehl. Gibt es irgendwelche?

+0

Sind sie Kinder der aktuellen Shell? –

+0

Ich rufe Programme und Skripte in Funktionen in der aktuellen Shell – tomtom

+2

Diese [Prozess Management] (http://mywiki.wooledge.org/ProcessManagement) Seite kann hier hilfreich sein. –

Antwort

4

Es ist eigentlich ziemlich einfach:

#!/bin/bash 
set -o monitor 
killAll() 
{ 
# code to kill all child processes 
} 

# call function to kill all children on SIGCHLD from the first one 
trap killAll SIGCHLD 

# start your child processes here 

# now wait for them to finish 
wait 

Sie müssen nur in Ihrem Skript wirklich vorsichtig sein, nur bash verwenden integrierte Befehle. Sie können keine-Dienstprogramme starten, die als ein separater Prozess ausgeführt werden, nachdem Sie den trap Befehl ausgegeben haben - jeder untergeordnete Prozess wird SIGCHLD senden - und Sie können nicht sagen, wo es herkam.

+1

Sicherlich möglich, andere SIGCHLDs zu unterscheiden. Speichern Sie eine Liste Ihrer Hintergrundprozesse ('foo & foo_pids + = ($!)'), Und prüfen Sie, ob einige von ihnen tot sind, wenn Sie eine SIGCHLD erhalten (über 'kill-0'). Jeder lebt -> er kam von woanders. –

+0

@CharlesDuffy Schön. Ich wünschte, ich hätte daran gedacht, wenn ich ein Skript für einen Kunden hacken müsste, ähnlich dem, was ich oben gepostet habe, alles unter extremem Zeitdruck. –

+1

Ein neuer spezieller Parameter (vielleicht '$ &'), der die Prozess-ID des Kinds enthält, verursachte 'SIGCHILD' (oder das' 'wait -n' 'zum Beenden verursachte) wäre nett. Vielleicht mache ich eine Feature-Anfrage für 4.5 – chepner

5

bash 4.3 wurde dem integrierten Befehl wait ein -n-Flag hinzugefügt, wodurch das Skript darauf wartet, dass das nächste untergeordnete Objekt abgeschlossen wird. Die -p Option zu jobs bedeutet auch, dass Sie möglicherweise nicht speichern müssen nicht die Liste der Bilder zu speichern, solange es keine Hintergrundjobs, die Sie nicht warten möchten.

# Run five concurrent processes 
for i in {1..5}; do 
    (longprocess) & 
done 

wait -n 
kill $(jobs -p) 

Beachten Sie, dass, wenn es einen anderen Hintergrund-Job anders als die fünf lange Prozesse ist, die zuerst abgeschlossen ist, wait -n beendet, wenn es abgeschlossen ist. Das würde auch bedeuten, dass Sie immer noch die Liste der zu tötenden Prozess-IDs speichern möchten, statt alles zu löschen, was auch immer jobs -p zurückgibt.

+0

* 'bash' 4.3 hinzugefügt ein' -n' Flag zu dem eingebauten 'wait' Befehl ... * Ich wünschte, ich hätte diese Option vor ein paar Jahren. . –