Was ich hier erreichen möchte, ist, dass ich über ein Skript drei verschiedene benutzerdefinierte Anwendungen gleichzeitig im Wartemodus laufen lasse. Wenn eine der Anwendungen beendet wird, gebe ich per Benachrichtigung eine Warnung aus oder drucke den Exit-Code aus.
Verwendetes System: Centos 6.8
Antwort1
Der wait
Befehl in bash
(4.3 und neuer) hat eine -n
Option:
Wenn die
-n
Option angegeben ist, wartet „wait“ auf die Beendigung eines Jobs und gibt seinen Beendigungsstatus zurück.
Das bedeutet, dass Sie
command1 &
command2 &
command3 &
wait -n
printf 'One command exited with exit code %d\n' "$?"
Antwort2
Sie können mit wait -n
warten, bis ein untergeordnetes Element beendet wird, und dann für jedes untergeordnete Element testen, ob es noch mit ausgeführt wird kill -0
, um zu sehen, welches gerade beendet wurde. Gehen Sie dazu folgendermaßen vor:
for f in 15 10 15; do
sleep $f &
PIDS+="$! "
done
wait -n
for f in $PIDS; do
if ! kill -0 $f 2> /dev/null; then
echo $f
fi
done
wait -n
Gibt nur den Beendigungsstatus des untergeordneten Elements zurück, nicht, welcher PID
es war.
Antwort3
Ich habe an Bash gedacht wait -n
, aber es teilt einem nicht mit, welcher Kindprozess beendet wurde. Wie wäre es mit einem einfachen Perl-Skript?
#!/usr/bin/perl
use strict;
use warnings;
use POSIX ":sys_wait_h";
sub spawn(@) {
my $pid = fork();
die "fork: $!" if not defined $pid;
if ($pid == 0) {
exec @_ or die "exec: $!";
}
return $pid;
}
# Commands to run
my $p1 = spawn '/bin/bash -c "sleep 6; kill $$"';
my $p2 = spawn '/bin/bash -c "sleep 4; exit 4"';
print "spawned PIDs $p1 and $p2\n";
while ((my $child = waitpid(-1, 0)) > 0) {
my $code = $? >> 8;
my $status = $? & 0xff;
printf "child %d finished with exit code %d (status/sig %d)\n", $child, $code, $status;
}
Antwort4
Mit Bash 5.1 oder neuer können Sie Folgendes tun:
while
wait -np id
status=$?
[ -n "$id" ]
do
echo "process of ID $id exited with status $status"
done
bash-5.2$ Hilfe warte Warten:Warten[-FN] [-p var] [Ausweis...] Warten Sie, bis der Auftrag abgeschlossen ist, und geben Sie den Beendigungsstatus zurück. Wartet auf jeden Prozess, der durch eine ID identifiziert wird. Dies kann eine Prozess-ID oder eine Auftragsspezifikation und meldet seinen Beendigungsstatus. Wenn die ID nicht gegeben, wartet auf alle derzeit aktiven Kindprozesse und die Rückgabe Status ist Null. Wenn die ID eine Auftragsspezifikation ist, wartet auf alle Prozesse in der Pipeline dieses Jobs. Wenn die Option -n angegeben ist, wird auf einen einzelnen Job aus der Liste der IDs gewartet. oder, wenn keine IDs angegeben sind, für den nächsten Auftrag, der abgeschlossen werden soll, und gibt seine Beendigungsstatus. Wenn die Option -p angegeben ist, die Prozess- oder Jobkennung des Jobs für die der Exit-Status zurückgegeben wird, wird der Variablen VAR zugewiesen. benannt durch das Optionsargument. Die Variable wird zunächst gelöscht, bevor beliebige Zuweisung. Dies ist nur sinnvoll, wenn die Option -n angegeben ist. Wenn die Option -f angegeben ist und die Jobsteuerung aktiviert ist, wartet angegebene ID zum Beenden, anstatt auf eine Statusänderung zu warten. Beendigungsstatus: Gibt den Status der letzten ID zurück; schlägt fehl, wenn die ID ungültig ist oder ein ungültiger Option angegeben ist, oder wenn -n angegeben ist und die Shell keine unwaited-for- Kinder.