smutbert hat geschrieben:Das Problem ist, dass die geschwungenen Klammern offensichtlich (an diese Möglichkeit habe ich gar nicht gedacht) eine neue Shell starten
Das tun sie nicht, bei
{} ist's definitiv dieselbe Shell, erst
() wuerde eine Subshell starten. Da du aber alles per
& in Jobs verwandelst, sehen die sich gegenseitig nicht:
Code: Alles auswählen
$ sleep 999 &
$ jobs
[1] + Running sleep 999
$ { jobs; }
[1] + Running sleep 999
$ { jobs; } &
$
Ich hab' da ein bisschen rumprobiert und man bekommt offensichtlich auch nicht "ohne weiteres" irgendwelche Daten zwischen den beiden Hintergrundprozessen ausgetauscht. Das kann man z.B. ueber den Umweg "Dateisystem" machen:
Code: Alles auswählen
#!/bin/sh
dir="$(mktemp -d)"
trap 'rm -r "$dir"' EXIT;
echo init;
{
echo one started;
sleep 3;
echo one killing;
kill "$(cat "$dir/two")";
} &
echo $! >"$dir/one";
{
echo two started;
sleep 5;
echo two killing;
kill "$(cat "$dir/one")";
} &
echo $! >"$dir/two";
wait %1 %2;
echo fini;
Der Code verwendet keine Features, wofuer's die
bash braeuchte und laeuft in der
dash einwandfrei. Die
bash schreibt einen Hinweis, dass die langsamere Job abgeschossen wurde ("Terminated") und das darauffolgende
wait meckert, wenn der zweite Job schon gekillt ist (interessanterweise nicht, wenn der erste fehlt...).
Und vielleicht gibt's ja noch eine simplere Variante wie ein externes
wait, was einfach blockt, bis es die als Argument uebergebene PID nicht mehr gibt. Die
wait*()-Syscalls scheinen sich aber allesamt auf Kindprozesse des eigenen Prozesses zu beschraenken, vermutlich muss man tatsaechlich regelmaessig pollen, wie's die Loesung von peschmae vorsieht.
Gruss Cae