linux - 为什么从用作监视服务的 bash 脚本启动的进程在脚本终止后仍然存在?

标签 linux bash process fork monit

我有一个 bash 脚本,我已将其设置为监控服务。该脚本以对 tail 的长时间运行调用结束,该调用将其输出通过管道传输到 nc 以发送到外部服务器。

我遇到的问题是,当我使用 monit 停止服务时,bash 脚本的进程终止,但该脚本进行的 tail 调用的进程仍然存在。我在下面展示了这种行为的示例。

$ sudo monit start service
$ ps aux | grep -E 'service|tail'
root     26215  0.0  0.0  17876   464 ?        S    18:31   0:00 /bin/bash -x /path/to/service.sh &>/var/log/service.log
root     26216  0.0  0.0   4344   352 ?        S    18:31   0:00 tail -q -n 0 -f /var/log/app.log /var/log/db.log /var/log/mail.log
root     26217  0.0  0.1  20736  1060 ?        S    18:31   0:00 nc server.foo.com 1234
$ sudo cat /var/run/service.pid
26215
$ sudo monit stop service
$ ps aux | grep -E 'service|tail'
root     26216  0.0  0.0   4344   352 ?        S    18:31   0:00 tail -q -n 0 -f /var/log/app.log /var/log/db.log /var/log/mail.log
root     26217  0.0  0.1  20736  1060 ?        S    18:31   0:00 nc server.foo.com 1234

我试过用几种不同的方式进行 tail 调用:

1)在前台,输出bash脚本PID到PID文件

echo "$$" > $PID_FILE
tail -q -n 0 -f $args | nc server.foo.com 1234

2) 在后台不使用子shell,将最后一个后台进程PID输出到PID文件

{ tail -q -n 0 -f $args | nc server.foo.com 1234; } &
echo "$!" > $PID_FILE

3) 在后台使用子shell,将子shell的PID输出到PID文件

( echo $BASHPID > $PID_FILE; tail -q -n 0 -f $args | nc server.foo.com 1234 ) &

奇怪的是,所有这些方法似乎都会导致上述行为:始终使用 bash 脚本 PID,当 monit 停止服务时 bash 脚本进程终止,tail 进程不会。

我想知道为什么会发生这种情况,以及如何在相关服务被 monit 终止时终止 bash 脚本调用的任何进程。

最佳答案

尝试:

bash -c "tail -q -n 0 -f $args | nc server.foo.com 1234"

关于linux - 为什么从用作监视服务的 bash 脚本启动的进程在脚本终止后仍然存在?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23662936/

相关文章:

linux - 使用 grep 和 ls -a 命令

linux - 在脚本中关闭 echo

bash - Docker Shell脚本未按预期参数化

java - Java中 fork 子进程的输出

python - 为什么我仍然得到 "E: Unable to locate package python-networkx"和 "E: Unable to locate package python-pystache"?

c++ - 将 C++ 代码从 Windows 移植到 Linux - 头文件区分大小写问题

linux - 如何使用 Bash 从文件运行命令?

linux - 遍历列表并创建目录(或者为什么这个循环中断)

python - 杀死python进程时杀死子进程?

java - "each JVM thread has its own program counter?"是什么意思