Bashスクリプトで複数のサブルーチンを起動して待ちます。誰でももう一方を終了し、スクリプトを終了する前にもう一方を終了します。
CMD1PID= CMD2PID= 出口トラップ(){ echo "トラップ終了:ジョブ終了..." sudo kill $CMD1PID $CMD2PID 出口 } セットBM トラップ終了_トラップ終了INT用語 sudo cmd1 --args & CMD1PID=$? sudo cmd2 --args & CMD2PID=$? $CMD1PID $CMD2PID を待ちます。
(参考としてGNU bash, version 4.2.37(1)-release (arm-unknown-linux-gnueabi)
Debian Weezyにあります)
残念ながら、これは正しく動作しないようです。私は次のようないくつかのバリエーションを試しました。
- コマンドの周りに中かっこを使用してから、シェルプロセスを明示的に終了します。つまり、
{ cmd1 --args ; kill -USR1 $$ ; } &
同様のプロセスを終了してUSR1をキャプチャします。 kill 0
終了時にまだ実行中のコマンドを終了するために使用されます。- トラップ - 欠点は、
CHLD
必要に応じてコマンドを切り替えることができないことです。最終的に切り替える必要があるかもしれません。sleep
...しかし、私がよく直面する問題は次のとおりです。
- いずれかのコマンドを終了しても、親 Bash プロセスが終了するか、他のコマンドは終了しません。
- 親 Bash プロセスを終了しても、両方のコマンドは終了しません。
おそらく、他のスクリプトの他のスクリプトが似たようなスクリプトを使って幸運に思われるので、sudoを使用する必要があるという要件が私を妨げているようです。 Bashでやりたいことをするための良い方法はありますか?
ベストアンサー1
2つの問題があります。興味深い子供たちがいつ終わるかを決定し、すべての子供たちを殺す必要があります。
1つ目は、組み込みの「待機」を使用できないという意味です。みんな子供(またはリスト内のすべての子供)には適していません。どの。 USR1に基づくあなたの提案はEXITだけでなく、それにも適しています。
2番目ははるかに難しいです。 sudoを使用しているため、実際にプロセスにシグナルを送信する権限がなく、ユーザーIDが一致するか、ルートである必要があります。
ファイルシステムやファイルハンドルベースのシグナルなどを試してみることができますが、正直なところ、これは他のスクリプト言語(Python、Perlなど)で理解しやすく、読みやすく、メンテナンスしやすく、複雑すぎるかもしれません。ターゲットユーザーの下でスクリプト全体を実行することをお勧めします。