7

「ps」または「サービスステータス(Linuxの場合)」を使用してプロセスステータスを定期的にチェックするスクリプト、またはフォークしてプロセスを待機するC / C ++で監視プログラムを見てきました...

bash を trap で使用して、SIGCLD が受信されたときにサブプロセスを再起動することは可能でしょうか?

次のアイデアでRedHat Linuxで基本的なスイートをテストしました(そして確かに機能しませんでした...)

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

開始されたbashスクリプトは、数秒間スリープして、今のところ終了します。

いくつかの問題が観察されました:

  • シェルがフォアグラウンドで起動すると、SIGCHLD は 1 回だけ処理されます。シグナル()のようなリセットシグナル処理をトラップしますか?
  • スクリプトとその子は SIGINT の影響を受けないようです。つまり、^C で停止することはできません。
  • 閉じることができないので、端末を閉じました。台本はHUPらしく、ゾンビの子がたくさん出てきました。
  • バックグラウンドで実行すると、スクリプトにより端末が停止しました

...とにかく、これはまったく機能しません。私はこのトピックについてほとんど知らないと言わざるを得ません。誰かがいくつかの実例を提案または提供できますか? そのような使用のためのスクリプトはありますか?

では、bashでwaitを使用するのはどうですか?

ありがとう

4

1 に答える 1

8

I can try to answer some of your questions but not all based on what I know.

  1. The line set -o monitor (or equivalently, set -m) turns on job control, which is only on by default for interactive shells. This seems to be required for SIGCHLD to be sent. However, job control is more of an interactive feature and not really meant to be used in shell scripts (see also this question).

    Also keep in mind this is probably not what you intended to do because once you enable job control, SIGCHLD will be sent for every external command that exists (e.g. every time you run ls or grep or anything, a SIGCHLD will fire when that command completes and your trap will run).

  2. I suspect the reason the SIGCHLD trap only appears to run once is because your trap handler contains a foreground infinite loop, so your script gets stuck in the trap handler. There doesn't seem to be a point to that loop anyways, so you could simply remove it.

  3. The script's "immunity" to SIGINT seems to be an effect of enabling job control (the monitor part). My hunch is with job control turned on, the sub-instance of bash that runs your script no longer terminates itself in response to a SIGINT but instead passes the SIGINT through to its foreground child process. In your script, the ^C i.e. SIGINT simply acts like a continue statement in other programming languages case, since SIGINT will just kill the currently running sleep 60, whereupon the while loop will immediately run a new sleep 60.

  4. When I tried running your script and then killing it (from another terminal), all I ended up with were two stray sleep processes.

  5. Backgrounding that script also kills my shell for me, although the behavior is not terribly consistent (sometimes it happens immediately, other times not at all). It seems typing any keys other than enter causes an EOF to get sent somehow. Even after the terminal exits the script continues to run in the background. I have no idea what is going on here.

Being more specific about what you want to accomplish would help. If you just want a command to run continuously for the lifetime of your script, you could run an infinite loop in the background, like

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

Note the & after the done.

For other tasks, wait is probably a better idea than using job control in a shell script. Again, it would depend on what exactly you are trying to do.

于 2011-07-21T17:13:30.770 に答える