2011-07-20 29 views
5

私は定期的に 'ps'や 'service status(Linux上)'を使ってプロセスステータスをチェックするスクリプトや、フォークしてプロセスを待つC/C++の監視プログラムを見たことがあります...トラップSIGCHLDを使用したbash restartサブプロセス?

I SIGCLDが受信したときにbashをトラップとともに使用してサブプロセスを再起動することが可能かどうか疑問に思いますか?

私が開始されたbashスクリプトは、ほんの数秒のための出口のために眠る何

(...と、確かにそれは動作しませんでした)、次のアイデアを
#!/bin/bash 
set -o monitor # can someone explain this? discussion on Internet say this is needed 
trap startProcess SIGCHLD 
startProcess() { 
    /path/to/another/bash/script.sh & # the one to restart 
    while [ 1 ] 
    do 
    sleep 60 
    done 
} 
startProcess 

をRedHatのLinux上での基本的なスイートをテストしています今。観察

いくつかの問題:シェルがフォアグラウンドで起動したとき

  • 、SIGCHLDは一度だけ処理されます。 signal()のようなリセット信号処理をトラップしますか?
  • スクリプトとその子は、SIGINTから免除されているように見えます。つまり、それらを停止できないことを意味します。^ C
  • 私は端末を閉じていません。スクリプトはHUPで、多くのゾンビの子供たちが残っているようです。
  • バックグラウンドで実行すると、スクリプトはとにかく、これがすべてでは動作しません...

を死ぬように端末を引き起こしました。私はこの話題についてあまり知りません。 誰かが提案したり、いくつかの実例を挙げることはできますか? このような使用のためのスクリプトはありますか?

bashでの使用待ちはどうですか?

おかげ

答えて

6

私はあなたの質問のいくつかに答えることを試みるが、すべて私が知っている 内容に基づいてすることはできません。

  1. set -o monitor(または同等に、set -m)は、インタラクティブシェルのデフォルトだけであるジョブ 制御、オンにします。これは、SIGCHLDの送信には が必要です。しかし、ジョブ制御は対話的な機能であり、実際にはシェルスクリプト (this questionも参照)で使用するつもりはないので、 のほうが多いです。

    また、あなたは、ジョブ制御を有効にすると、SIGCHLDがのために例えば(あなたがlsまたはgrepまたは 何かを実行するたびに存在するすべての 外部コマンドが送信されますので、これはあなたが を行うことを意図したもので、おそらくではありません覚えておいてくださいそのコマンドが完了するとSIGCHLDが起動し、トラップ が実行されます)。

  2. 私はあなたのトラップハンドラは、フォアグラウンド無限ループが含まれているので、あなたの スクリプトがトラップ・ハンドラにはまりのでSIGCHLDトラップは一度だけ実行するように見える理由は である疑いがあります。とにかくそのループにポイント が存在しないように思われるので、単純に削除することができます。

  3. SIGINTに対するスクリプトの "免除"は、 ジョブ制御(モニタ部分)を有効にする効果があるようです。スクリプトを実行するbashのサブインスタンスは、 自体がSIGINTに応答して終了するのではなく、代わりにSIGINTを介して のフォアグラウンドの子プロセスに渡されます。 SIGINTだけですぐに新しいsleep 60を実行するwhileループ、そこで、現在実行中のsleep 60、 を殺すので、あなたのスクリプトでは、^CすなわちSIGINT は単に、他のプログラミング言語 場合continue文のような役割を果たします。

  4. スクリプトを実行してから別の 端末から強制終了しようとしたとき、私は2つの迷い睡眠プロセスで終わった。 行動が(時にはそれが、すぐに他の回すべてではないが 起こる)ひどく一貫していないものの、そのスクリプトをバックグラウンド化

  5. も、私のためにシェルを殺します。他のキーを入力しているようです Enterキーを押すと何とかEOFが送られます。端末 が終了しても、スクリプトはバックグラウンドで実行され続けます。私は考えていない ここで何が起こっている。

あなたが達成したいことをより具体的にすることが役立ちます。 あなただけのコマンドは スクリプトの寿命のために継続的に実行したい場合は、

while true; do 
    some-command 
    echo some-command finished 
    echo restarting some-command ... 
done & 

done&のように、バックグラウンドで無限ループを実行することができます。

他のタスクの場合は、 をシェルスクリプトで使用するよりも、おそらく、waitが良い考えです。繰り返しますが、正確に何をしようとしているかによって異なります。

+0

あなたの共有のためにジミーに感謝し、ひどいスクリプトをテストしました。私は試みを止め、伝統的な方法でそれをやりました。しかし、私は "待機"を試しました、それは本当に基本的なシナリオでは非常にうまくいきます。 [$ {thepid} -ne場合SIGINT SIGTERM STOPNOW = 1 ! - '#/ binに/ bashの thepid = 0 STOPNOW = 0 セットは トラップクリーンアップSIGINTをSIGTERM クリーンアップ(){ トラップを監視-o 0]、その後 は が ./trial.sh& thepid = $を開始エコーん ] [$ {STOPNOW} -ne 1一方、$ {thepid} キル$ {thepid} Fiの } を殺すエコー! echo "$ {thepid}を待っています" 待ちます$ {thepid} done exit 0 ' –

関連する問題