- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在脚本中看到监控程序使用“ps”或“服务状态(在 Linux 上)”定期检查进程状态,或者在 C/C++ 中 fork 并等待进程...
我想知道是否可以将 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 脚本只是休眠几秒钟,然后暂时退出。
观察到的几个问题:
...无论如何,这根本行不通。我不得不说我对这个话题知之甚少。有人可以建议或提供一些工作示例吗?是否有用于此类用途的脚本?
那么在 bash 中使用 wait 怎么样?
谢谢
最佳答案
我可以尝试回答你的一些问题,但不是所有基于我的知道。
set -o monitor
行(或等效的 set -m
)打开作业控制,它仅在交互式 shell 中默认打开。这似乎需要发送 SIGCHLD。但是,作业控制更多一种交互式功能,并不是真的要在 shell 脚本中使用(另请参见 this question)。
另请记住,这可能不是您打算做的因为一旦启用作业控制,SIGCHLD 将被发送给 every存在的外部命令(例如,每次运行 ls
或 grep
或任何东西,当该命令完成并且您的陷阱时,SIGCHLD 将触发将运行)。
我怀疑 SIGCHLD 陷阱似乎只运行一次的原因是因为你的陷阱处理程序包含一个前台无限循环,所以你的脚本卡在陷阱处理程序中。似乎没有意义无论如何到那个循环,所以你可以简单地删除它。
脚本对 SIGINT 的“免疫力”似乎是启用作业控制(监视器部分)。我的直觉是打开作业控制,运行脚本的 bash 子实例不再终止本身响应 SIGINT,而是将 SIGINT 传递给它的前台子进程。在您的脚本中, ^C
即 SIGINT就像其他编程语言中的 continue
语句一样在这种情况下,由于 SIGINT 只会杀死当前正在运行的 sleep 60
,于是 while 循环将立即运行一个新的 sleep 60
。
当我尝试运行您的脚本然后终止它时(从另一个终端),我最终得到的只是两个杂散的 sleep 过程。
后台脚本也为我杀死了我的 shell,尽管行为不是非常一致(有时会发生立即,其他时候根本没有)。似乎键入其他任何键比 enter 导致 EOF 以某种方式发送。即使在终端之后退出脚本继续在后台运行。我不知道这是怎么回事。
更具体地说明您想要完成的事情会有所帮助。如果您只需要一个命令在您的生命周期内连续运行脚本,你可以在后台运行一个无限循环,比如
while true; do
some-command
echo some-command finished
echo restarting some-command ...
done &
注意 done
之后的 &
。
对于其他任务,wait
可能比使用作业控制更好在 shell 脚本中。同样,这取决于您到底在尝试什么做。
关于bash 使用陷阱 SIGCHLD 重新启动子进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6769414/
在下面的代码中,我期望的是控制台打印十个 SIGCHLD caught。我已经通过将 sa_flags 设置为 SA_SIGINFO 并使用 sa_sigaction 而不是 sa_handler 来
在编译我的 C 程序以使用 UDP 实现多个客户端服务器聊天程序时,我遇到了一些错误..我能够纠正其中一些错误,但无法纠正其他一些错误..他们是......: 1) 未知类型名称 sig_atomic
在运行 Linux 2.6.35+ 的系统中,我的程序创建许多子进程并监视它们。如果子进程死亡,我会进行一些清理并再次生成该进程。我使用 signalfd() 来获取进程中的 SIGCHLD 信号。
我需要检测我的后台进程之一何时退出。因此,我安装了一个陷阱。 run_gui 和 run_ai1 是简单的 exec 函数。 run_gui & gui_pid=$! run_ai1 & ai1_pi
我打算在父进程休眠 10 秒时将以下代码 fork 并作为子进程执行“ sleep 3”。我希望父进程在 3 秒后收到 SIGCHLD,当“ sleep 3”结束时。 这不会发生,相反我得到: mai
我需要正确处理 SIGCHLD。我如何将它与我现有的代码一起使用?目前我等不及子进程了,除非我使用 0 而不是 WNOHANG|WUNTRACED。 status = 0; pid_t child,
我正在尝试创建一个管理其他进程的进程,如果一个 child 死了,那么 parent 会重新启动该进程以及依赖于它的进程。 问题是我注意到,如果我在这个结构的中间重新启动一个进程时创建了一个进程的树结
我无法理解以下程序的输出。我观察到子进程返回后,父进程在 wait() 之前没有休眠 3 秒。如果 SIGCHLD 设置为默认处理程序,则它会休眠 3 秒,调用等待并按预期返回。这里究竟发生了什么??
在运行 Linux 2.6.35+ 的系统中,我的程序创建了许多子进程并监视它们。如果子进程死亡,我会进行一些清理并再次生成该进程。我使用 signalfd() 在我的进程中获取 SIGCHLD 信号
我有一个 C 程序,它每分钟轮询一次硬件传感器,并将读数添加到数据库中。为了确保读数更接近于每分钟(而不是每分钟 + 开销时间),该程序创建了一个 child 来完成实际工作,然后在创建另一个 chi
我有一个在 Linux 3.12 上运行的 C 程序。该程序产生几个子进程。其中一个进程会生成一个线程,该线程运行一段时间然后终止。当该子进程运行时,它会执行 epoll_wait()。 epoll_
我正在尝试制作一个简单的 shell,并添加功能以使用 & 在后台运行进程。在我的主要方法中我基本上有: int main() { if (signal(SIGCHLD, handle) == S
我的程序上有一个 SIGCHLD 处理程序,它捕获僵尸进程。 如何避免在执行多个 fork() 调用和 waitpid() 调用的代码部分中调用 SIGCHLD 处理程序? 因为现在,当我进行 for
我的父进程无法捕获 SIGCHLD,即使它处于 waitpid(SIGCHLD... 状态。尝试从子级向父级提供显式的kill(SIGCHLD ..)以测试父级是否没有收到信号。而且风格是AIX...
这是我的信号处理程序: pid_t pid; int status; while (pid = waitpid(-1, &status, WNOHANG|WUNTRACED|WCONTINUED))
我在开头声明这是一项家庭作业,并且在编写 SIGCHLD 处理程序时我陷入了困境。我需要访问子进程中的变量。 #include #include #include #include #incl
我在脚本中看到监控程序使用“ps”或“服务状态(在 Linux 上)”定期检查进程状态,或者在 C/C++ 中 fork 并等待进程... 我想知道是否可以将 bash 与 trap 一起使用并在收到
我目前正在使用 C++ 构建一个小型 shell。 用户可以在提示符下输入作业,例如 exe1 && exe2 &。与 BASH shell 类似,如果 exe1 成功退出,我只会执行 exe2。此外
这是我的代码,我已经简化了它。 #include #include #include #include void signal_handle(int sig) { int status
我正在阅读一篇关于信号的文章,我不确定这部分代码在做什么。有人可以为我解释一下吗?这篇文章是关于创建 TCP un-blocked 服务器。 struct sigaction sigchldActio
我是一名优秀的程序员,十分优秀!