複数の異なるコンピュータでリソースを大量に使用する長いコマンドを実行するシェルスクリプトがあります。
各コンピュータでスクリプトを並列に実行するために、forループの各リモートコマンドの後に&記号があります。
initialize-cluster.sh
:
while read host;
do
ssh -f "$host" \"/home/user/allocate.sh\" &
done < ~/cluster
しかし、forループの終わりにシェルプロンプトが表示されないことがわかりました。これにより、すべてのコンピュータでinitialize-cluster.sh
実行が完了した後に他のスクリプトを実行できなくなります。allocate.sh
たとえば、次のコマンドを実行したいとします。
./initalize-cluster.sh && ./execute-something-else.sh
しかし、initialize-cluster
まだ「完了」しているわけではありません。
allocate.sh
リモートシステム上のすべてのスクリプトが完了した後にのみ、後続のコマンドを実行したいと思います。
答え1
このスクリプトの内容は、次のコマンドを実行したりシェルプロンプトに戻ることを妨げてはいけません。プロンプトが消えたように見えるのは、シェルに戻ってから到着するリモートスクリプトの出力です。これを防ぐには、stdout / stderrをログファイルにリダイレクトできます。
リモートコマンドがバックグラウンドで実行されているため、元のスクリプトが完了します。今後スクリプトallocate
の実行が完了しました。次のコマンドは、初期化が完了したとは想定できません。すべての初期化を並列に開始し、すべてが完了するのを待つには、次のようにします。
#!/bin/sh
while read host
do
ssh "$host" "/home/user/allocate.sh" &
done < ~/cluster
wait
それはうまくいきます:
./initialize-cluster.sh && ./execute-something-else.sh
ここで重要なのは、wait
サブプロセスが完了するのを待つコマンドです。