バックグラウンドコマンドを待つシェルスクリプト


12

私はスクリプトを書いていますが、それを行う方法を見つけることができない何かが必要です...

バックグラウンドでコマンド「command1&」を作成し、スクリプトのどこかでコマンドが終了するのを待ってからcommand2を実行する必要があります。基本的に、私はこれが必要です:

注:各コマンドは特定のディレクトリで実行されます!whileループの最後に、command1が4つのディレクトリを作成しました。それぞれが特定のプロセスを実行するため、実行中のプロセスの合計は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

私はwaitpidプロセス番号を持つコマンドについて何かを見ましたが、それもうまくいきませんでした。


あなたはコントロールしていcommand1ますか?4つのプロセスのPIDを返すように変更できますか?
テルドン

はい!私はすでにそれを持っています:)
ジョアンマカオ14

それに応じて回答を更新しました。それがあなたの予想と一致するかどうか教えてください。
ローランC. 14

このQはこの1に関連しているunix.stackexchange.com/questions/100801/...。唯一の違いは、バックグラウンドプロセスからPIDを取得する必要があることです。ここで示したように、$!変数を使用してこれを取得し、waitコマンドに渡すことができます。$!最後のバックグラウンドPIDが$$含まれ、最後のプロセス実行のPIDが含まれます。
slm

3
さて、スクリプトはまったく意味をなしません。構文エラーと奇妙なことが至る所にあります。実際のスクリプトを見せていただけますか?なぜコマンドを調達するのですか?なぜそれらを実行しないのですか?
テルドン

回答:


22

このコマンドwait PIDを使用して、プロセスが終了するのを待つことができます。

次のコマンドで最後のコマンドのPIDを取得することもできます $!

あなたの場合、次のようなものが機能します:

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

編集後、複数のPIDがあり、それらを知っているので、それを行うことができます。

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

編集後、作成されたPID(xxxxx、yyyyy、xxyyy、yyxxx)がわかっている場合は、待機するPIDのリストとともにwaitを使用できます(manを参照)。それらを知らない場合、多分あなたはcommand1にそれらを集めることができます(command1とはあなた自身のスクリプトですか?)
ローランC.

そもそもそれらが正しくグループ化されていることを確認するのが最善でしょう。それがどのように行われるかについては、私の答えをご覧ください。
mikeserv 14

4

これを行う最もクリーンな方法comamnd1は、起動されたプロセスのPIDを返し、wait@ LaurentCのanswerで示唆されているように、それらのそれぞれを使用することです。

別のアプローチは次のようなものになります。

## 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

申し訳ありませんが、まだ機能していません。質問をもう一度改善します。
ジョアンマカオ14

0

次の方法を使用する場合、whileループの後に特別な「すべてのプロセスを待機する」必要はないかもしれません。ループは、電流command1が完了するのを待ってから、先頭に戻ります。アドバイスと同様に注意してください。注意してください、私がしたこと& wait $!はあなたのの最後に追加することだけでしたcommand1

a=1
while [$a -lt 4 ]
     . command1  & wait $!
   #Generates 1 Process  
     a= `export $a +1`
done
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.