bash 使用陷阱 SIGCHLD 重新启动子进程?

发布于 2024-11-25 08:40:46 字数 847 浏览 2 评论 0原文

我见过监控程序要么在使用“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 脚本只是休眠几秒钟然后暂时退出。

观察到的几个问题:

  • 当 shell 在前台启动时,SIGCHLD 将仅被处理一次。 trap 是否像 signal() 一样重置信号处理?
  • 该脚本及其子脚本似乎不受 SIGINT 的影响,这意味着它们不能被 ^C 停止
  • ,因为无法关闭,我关闭了终端。剧本好像是HUP,留下了很多僵尸小孩。
  • 当在后台运行时,脚本导致终端死机

......无论如何,这根本不起作用。我不得不说我对这个话题了解太少了。 有人可以建议或给出一些可行的例子吗? 有这样的用途的脚本吗?

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

谢谢

I've seen monitoring programs either in scripts that check process status using 'ps' or 'service status(on Linux)' periodically, or in C/C++ that forks and wait on the process...

I wonder if it is possible to use bash with trap and restart the sub-process when SIGCLD received?

I have tested a basic suite on RedHat Linux with following idea (and certainly it didn't work...)

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

what the bash script being started just sleep for a few seconds and exit for now.

several issues observed:

  • when the shell starts in foreground, SIGCHLD will be handled only once. does trap reset signal handling like signal()?
  • the script and its child seem to be immune to SIGINT, which means they cannot be stopped by ^C
  • since cannot be closed, I closed the terminal. The script seems to be HUP and many zombie children left.
  • when run in background, the script caused terminal to die

... anyway, this does not work at all. I have to say I know too little about this topic.
Can someone suggest or give some working examples?
Are there scripts for such use?

how about use wait in bash, then?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

爱你不解释 2024-12-02 08:40:46

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

  1. set -o monitor(或等效的set -m)启动作业
    控制,默认情况下仅对交互式 shell 启用。这似乎
    需要发送 SIGCHLD。然而,工作控制更多的是
    交互式功能,并不真正适合在 shell 脚本中使用
    (另请参见 这个问题)。

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

  2. 我怀疑 SIGCHLD 陷阱只出现一次的原因是
    因为你的陷阱处理程序包含一个前台无限循环,所以你的
    脚本卡在陷阱处理程序中。似乎没有什么意义
    无论如何,你可以简单地删除它。

  3. 脚本对 SIGINT 的“免疫”似乎是启用的效果
    作业控制(监视器部分)。我的预感是打开作业控制,
    运行脚本的 bash 子实例不再终止
    本身响应 SIGINT,而是将 SIGINT 传递给
    它的前台子进程。在您的脚本中, ^C 即 SIGINT
    只是像其他编程语言中的 continue 语句一样
    这种情况下,由于 SIGINT 只会终止当前正在运行的 sleep 60
    随后 while 循环将立即运行一个新的 sleep 60

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

  5. 尽管如此,将该脚本作为后台也会杀死我的 shell
    行为并不是非常一致(有时会发生
    立即,其他时候则根本不)。似乎输入任何其他键
    比 Enter 导致 EOF 以某种方式发送。即使在航站楼之后
    退出脚本继续在后台运行。我不知道
    这里发生了什么。

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

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

注意 done 之后的 &

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文