Shell-Skript wartet auf Hintergrundbefehl

12

Ich schreibe ein Drehbuch, aber es gibt etwas, das ich brauche, damit ich es nicht schaffen kann ...

Ich muss einen Befehl im Hintergrund "command1 &" ausführen und dann irgendwo im Skript darauf warten, dass er beendet wird, bevor ich command2 ausführe. Grundsätzlich brauche ich das:

HINWEIS: Jeder Befehl wird in einem bestimmten Verzeichnis ausgeführt! Am Ende der while-Schleife hat mein Befehl1 4 Verzeichnisse erstellt, in denen jeweils der spezifische Prozess ausgeführt wird, sodass insgesamt 4 Prozesse ausgeführt werden

a=1

while [$a -lt 4 ]

     . command1
   #Generates 1 Process  

     a= `export $a +1`
done

   #Wait until the 4 process end and then run the command2 

    . command2

Ich habe etwas über einen waitBefehl mit der PID-Prozessnummer gesehen, aber das hat auch nicht funktioniert.

Joao Macau
quelle
Kontrollierst du command1? Können Sie es so ändern, dass es die PIDs der 4 Prozesse zurückgibt?
Terdon
Ja! Ich habe das schon :)
Joao Macau
Ich habe meine Antwort entsprechend aktualisiert. Sagen Sie mir, ob es Ihren Erwartungen entspricht.
Laurent C.
Dieses Q ist mit diesem verwandt: unix.stackexchange.com/questions/100801/… . Der einzige Unterschied besteht darin, dass Sie die PID aus einem Hintergrundprozess abrufen müssen. Sie können diese $!Variable verwenden, um sie an den waitBefehl zu übergeben, wie ich dort gezeigt habe. $!enthält die zuletzt hinterlegte PID, während $$die PID des letzten Prozesslaufs enthalten ist.
slm
3
OK, jetzt macht dein Skript überhaupt keinen Sinn. Es gibt überall Syntaxfehler und Fremdheiten. Können Sie uns das aktuelle Drehbuch zeigen? Warum beziehen Sie Befehle? Warum nicht einfach ausführen?
Terdon

Antworten:

22

Mit dem Befehl können Sie wait PIDwarten, bis ein Prozess beendet ist.

Sie können auch die PID des letzten Befehls mit abrufen $!

In Ihrem Fall würde so etwas funktionieren:

command1 & #run command1 in background
PID=$! #catch the last PID, here from command1
command2 #run command2 while command1 is running in background
wait $PID #wait for command1, in background, to end
command3 #execute once command1 ended

Nach der Bearbeitung können Sie Folgendes tun, da Sie über mehrere PIDs verfügen und diese kennen:

command1 & #run command1 in background
PID1=xxxxx
PID2=yyyyy
PID3=xxyyy
PID4=yyxxx
command2 #run command2 while command1 is running in background
wait $PID1 $PID2 $PID3 $PID4 #wait for the four processes of command1, in background, to end
command3 #execute once command1 ended
Laurent C.
quelle
Wenn Sie nach der Bearbeitung wissen, dass eine PID erstellt wurde (xxxxx, yyyyy, xxyyy, yyxxx), können Sie auch wait mit der Liste der PIDs verwenden, auf die gewartet werden soll (siehe man). Wenn Sie sie nicht kennen, können Sie sie vielleicht in command1 zusammenfassen (was ist command1? Ein eigenes Skript?)
Laurent C.
Wahrscheinlich am besten, um sicherzustellen, dass sie überhaupt richtig gruppiert sind. Siehe meine Antwort für eine Idee, wie es gemacht werden könnte.
mikeserv
4

Am comamnd1einfachsten ist es, wenn Sie die PIDs der gestarteten Prozesse zurückgeben und waitauf jeden von ihnen anwenden, wie in der Antwort von @ LaurentC angegeben .

Ein anderer Ansatz wäre etwa so:

## Create a log file
logfile=$(mktemp)

## Run your command and have it print into the log file
## when it's finsihed.
command1 && echo 1 > $logfile &

## Wait for it. The [ ! -s $logfile ] is true while the file is 
## empty. The -s means "check that the file is NOT empty" so ! -s
## means the opposite, check that the file IS empty. So, since
## the command above will print into the file as soon as it's finished
## this loop will run as long as  the previous command si runnning.
while [ ! -s $logfile ]; do sleep 1; done

## continue
command2
terdon
quelle
Entschuldigung, aber es funktioniert immer noch nicht. Ich werde meine Frage noch einmal verbessern!
Joao Macau
0

Wenn Sie die folgende Methode verwenden, benötigen Sie nach der while-Schleife möglicherweise kein spezielles "Warten auf alle Prozesse". Die Schleife wartet auf den Abschluss des Stroms command1, bevor sie nach oben wechselt. Bitte seien Sie vorsichtig, wie bei jedem Ratschlag. Beachten Sie, das einzige, was ich getan habe, war & wait $!, das Ende Ihrer Liste zu ergänzen command1.

a=1
while [$a -lt 4 ]
     . command1  & wait $!
   #Generates 1 Process  
     a= `export $a +1`
done
Marius M
quelle