7

我已经看到监视程序在脚本中使用“ps”或“服务状态(在 Linux 上)”定期检查进程状态,或者在 C/C++ 中分叉并等待进程......

我想知道是否可以使用带有陷阱的bash并在收到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 脚本只是休眠几秒钟然后退出。

观察到几个问题:

  • 当 shell 在前台启动时,SIGCHLD 将只处理一次。陷阱复位信号处理是否像信号()?
  • 脚本及其子进程似乎对 SIGINT 免疫,这意味着它们不能被 ^C 阻止
  • 由于无法关闭,我关闭了终端。剧本似乎是HUP,留下了许多僵尸孩子。
  • 在后台运行时,脚本导致终端死机

...无论如何,这根本不起作用。我不得不说我对这个话题知之甚少。有人可以建议或给出一些工作示例吗?有这种用途的脚本吗?

那么在 bash 中使用 wait 怎么样?

谢谢

4

1 回答 1

8

我可以尝试回答您的一些问题,但不是全部基于我所知道的。

  1. 该行set -o monitor(或等效地,set -m)打开作业控制,默认情况下仅对交互式 shell 启用。这似乎是发送 SIGCHLD 所必需的。但是,作业控制更多的是一种交互功能,并不真正打算在 shell 脚本中使用(另请参见这个问题)。

    另请记住,这可能不是您打算做的,因为一旦您启用作业控制,将为存在的每个 外部命令发送 SIGCHLD(例如,每次您运行lsgrep其他任何事情时,当该命令完成并且您的陷阱将运行)。

  2. 我怀疑 SIGCHLD 陷阱只运行一次的原因是因为您的陷阱处理程序包含前台无限循环,因此您的脚本卡在陷阱处理程序中。无论如何,该循环似乎没有意义,因此您可以简单地将其删除。

  3. 脚本对 SIGINT 的“免疫”似乎是启用作业控制(监视器部分)的效果。我的预感是在作业控制打开的情况下,运行脚本的 bash 子实例不再响应 SIGINT 而终止自身,而是将 SIGINT 传递到其前台子进程。在您的脚本中,^Cie SIGINT 就像continue其他编程语言案例中的语句一样,因为 SIGINT 只会杀死当前正在sleep 60运行的sleep 60.

  4. 当我尝试运行您的脚本然后(从另一个终端)杀死它时,我最终得到的只是两个杂散的睡眠进程。

  5. 后台运行该脚本也为我杀死了我的 shell,尽管行为并不是非常一致(有时它会立即发生,有时根本不会发生)。似乎键入除 enter 以外的任何键都会导致 EOF 以某种方式发送。即使在终端退出后,脚本也会继续在后台运行。我不知道这里发生了什么。

更具体地说明你想要完成的事情会有所帮助。如果您只想让命令在脚本的整个生命周期内连续运行,您可以在后台运行无限循环,例如

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

注意. &_done

对于其他任务,wait可能比在 shell 脚本中使用作业控制更好。同样,这取决于您到底要做什么。

于 2011-07-21T17:13:30.770 回答