Shell-Skript wartet auf Hintergrundbefehl

Ich schreibe ein Skript, aber ich brauche etwas, das ich nicht finden kann …

Ich muss im Hintergrund einen Befehl „command1 &“ ausführen und dann irgendwo im Skript warten, bis er beendet ist, bevor ich Befehl2 ausführe. Grundsätzlich , Ich brauche Folgendes:

HINWEIS: Jeder Befehl wird in einem bestimmten Verzeichnis ausgeführt! Am Ende der while-Schleife hat mein Befehl1 4 Verzeichnisse erstellt, in denen in jedem der spezifische Prozess ausgeführt wird, also die Gesamtheit des Prozesses Laufen sind 4

 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 eine wait Befehl mit der PID-Prozessnummer, aber das hat auch nicht funktioniert.

Kommentare

  • Steuern Sie command1? Können Sie es so ändern, dass es die PIDs der 4 Prozesse zurückgibt?
  • Ja! Ich habe das schon 🙂
  • Ich habe meine Antwort entsprechend aktualisiert. Sagen Sie mir, ob es Ihren Erwartungen entspricht.
  • Dieses Q hängt mit diesem zusammen: unix.stackexchange.com/questions/100801/… . Der einzige Unterschied besteht darin, dass Sie die PID aus einem Hintergrundprozess abrufen müssen. Sie können die Variable $! verwenden, um dies abzurufen, und sie an den Befehl wait übergeben, wie ich dort gezeigt habe. $! enthält die letzte PID im Hintergrund, während $$ die PID des letzten Prozesslaufs ' enthält
  • OK, jetzt macht Ihr Skript überhaupt keinen Sinn mehr. Es gibt überall Syntaxfehler und Fremdheit. Können Sie uns das aktuelle Skript zeigen? Warum beziehen Sie Befehle? Warum nicht einfach ausführen?

Antwort

Sie können den Befehl wait PID, um auf das Ende eines Prozesses zu warten.

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

In 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 Ihrer Bearbeitung können Sie Folgendes tun, da Sie mehrere PIDs haben 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 

Kommentare

  • Wenn Sie nach der Bearbeitung die erstellte PID kennen (xxxxx, yyyyy, xxyyy, yyxxx) ) können Sie auch wait mit der Liste der zu wartenden PIDs verwenden (siehe man). Wenn Sie sie ' nicht kennen, können Sie sie möglicherweise in Befehl1 zusammenfassen (was ist Befehl1? Ein eigenes Skript?)
  • Wahrscheinlich am besten, um sie sicherzustellen ' wurde an erster Stelle korrekt gruppiert. In meiner Antwort finden Sie eine Vorstellung davon, wie es gemacht werden könnte.

Antwort

Der sauberste Weg, dies zu tun Es wäre, wenn Ihre comamnd1 die PIDs der gestarteten Prozesse zurückgibt und wait für jede von ihnen verwendet, wie von @LaurentC „s Antwort .

Ein anderer Ansatz wäre ungefähr 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 

Kommentare

  • Entschuldigung, aber immer noch nicht funktioniert. Ich werde meine Frage noch einmal verbessern!

Antwort

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 die aktuelle command1, um den Vorgang abzuschließen, bevor er wieder nach oben wechselt. Bitte gehen Sie vorsichtig vor, wie bei allen Ratschlägen. Beachten Sie, dass ich nur & wait $! am Ende Ihres command1.

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

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.