我有这个与主管一起运行的bash脚本
#!/bin/bash
DIR="/home/files"
while read file; do
IFS=', ' read -r -a array <<< "$file"
echo "Time: ${array[0]}"
echo "File: ${array[1]}"
#... doing something with the file
done < <(inotifywait -m -r -e close_write "$DIR" --timefmt "%d_%b_%Y" --format "%T %w%f")
它运行得很好,但是当我执行supervisorctl stop all
时,即使程序停止,inotifywait
进程也会继续运行。有没有办法在bash脚本退出后终止inotifywait
?
修改1 该程序的主管配置是
[program:watch]
command=/root/watch_data.sh
user=root
stderr_logfile=/var/log/supervisord/watch_cloud.log
stdout_logfile=/var/log/supervisord/watch_cloud.log
autorestart=true
stopsignal=INT
答案 0 :(得分:4)
我认为您在执行supervisorctl stop all
时缺少将kill信号传播到所有子进程的选项。通常一个人有一个父进程和子进程,当父进程获得SIGTERM
/ SIGINT
时,它将/应该有一个协调的方式,应该是负责发送信号的人或通过其他方式关闭子进程
supervisord
只提供了一个选项。来自official documentation
stopasgroup
如果为true,则该标志会使主管将停止信号发送到整个进程组并暗示
killasgroup
为真。这对于诸如调试模式下的Flask之类的程序非常有用,它们不会将停止信号传播给它们的子项,从而使它们成为孤立状态。
killasgroup
如果为true,当诉诸程序发送
SIGKILL
以终止它时,将其发送到整个进程组,同时照顾其子代,例如使用多处理的Python程序。
当Supervisor转向发送killasgroup
时,SIGKILL
会终止该组中的所有进程。这个想法是,当这个过程很好玩时,应该允许它自己处理它的孩子。但当它行为不端并需要强制选择时,整个过程组才会终止。
还记得传播SIGINT
,虽然默认操作是优雅地终止,但进程可以忽略。如果您不太担心脚本的正常终止,您可以传递SIGKILL
,这相当于Linux中kill -9
生成的信号。
因此,您的超级用户配置文件中有以下选项
[program:watch]
command=/root/watch_data.sh
user=root
stderr_logfile=/var/log/supervisord/watch_cloud.log
stdout_logfile=/var/log/supervisord/watch_cloud.log
stopasgroup=true
killasgroup=true
stopsignal=KILL