Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 将SIGTERM发送到所有进程_Bash_Shell_Docker - Fatal编程技术网

Bash 将SIGTERM发送到所有进程

Bash 将SIGTERM发送到所有进程,bash,shell,docker,Bash,Shell,Docker,我有一个启动多个进程的bash脚本调用run.sh #!/bin/bash proc1 & proc2 & proc3 & final # this runs until sigterm 当我执行run.sh并向run.sh发送一个SIGTERM时,我不认为SIGTERM被发送到final,也不认为它被发送到proc1、proc2和proc3。注意,在这个用例中,这是一个docker容器,它运行run.sh,运行docker stop是我试图发送SIGTERM的方式 b

我有一个启动多个进程的bash脚本调用
run.sh

#!/bin/bash
proc1 &
proc2 &
proc3 &
final # this runs until sigterm
当我执行
run.sh
并向run.sh发送一个SIGTERM时,我不认为SIGTERM被发送到
final
,也不认为它被发送到
proc1
proc2
proc3
。注意,在这个用例中,这是一个docker容器,它运行
run.sh
,运行
docker stop
是我试图发送SIGTERM的方式

bash脚本向它启动的所有进程发送sigterm的最简单方法是什么?我能想到的唯一方法是用
启动
final
,然后在
run.sh
中执行while循环

编辑-我尝试过,但似乎不起作用: 在
run.sh中

#!/bin/bash
_term() { 
  echo "Caught SIGTERM signal!" 
}
trap _term SIGTERM
echo "hi"
sleep 100000 &
wait $!

运行docker stop时,我从未看到捕获到的SIGTERM信号

正确,我会将它们全部收集在一个数组中,然后在完成后向它们中的每一个发送一个信号。我会使用类似于
awk'{system(“kill-15”$1)}'

您说过您在Docker容器中运行该脚本。您能否提供有关如何启动容器以及如何调用
run.sh
的更多详细信息

当调用
docker stop
或容器接收到直接的
SIGTERM
时,包含PID 1的进程将接收它。当您的
run.sh
创建在后台运行的子进程时,它还必须向它们转发信号

因此,使用
&
在bash脚本中创建后台子进程不是一个好方法。使用a将是一种很好的做法,因为它可以正确地处理信号并将其转发给其子进程,而无需进一步编写脚本

此外,
supervisord
不应作为shell子进程本身启动。如果在
Dockerfile
中指定此作为容器命令,则会发生这种情况:

CMD /usr/bin/supervisord
相反,它应该看起来像:

CMD ["/usr/bin/supervisord"]

这样,主管将成为具有PID 1的根进程,并将正确接收所有信号并将其重定向到其子进程。

使用
作业-p
获取任何后台作业的进程ID,然后将其传递给
kill

trap 'kill $(jobs -p)' TERM

proc1 &
proc2 &
proc3 &

wait

所以my run.sh是为docker容器运行的CMD。但是我很困惑-为什么不使用bash on run.sh工作来捕获信号(仅供参考,我只是尝试了,但没有),因为您将明确需要使用
trap
s,如前所述。此外,我已经验证了我的run.sh从PID 1I开始,我不会花太多时间让脚本工作。在Docker环境中,这通常是一种不好的做法,而且很难像您刚刚经历的那样运行。每个容器只能使用一个进程,或者使用如上所述的主管。但请看我的最新示例。这不应该起作用吗?您需要将
\u term
函数名作为字符串传递,例如:
trap'\u term'SIGINT
@h3nrik我试过了'\u term',仍然不起作用您的脚本在
睡眠
退出后才能运行处理程序,因为它不会被中断。使用
sleep 100000&
在后台运行它;然后执行
wait
命令,可以中断该命令以运行hander。顺便说一句,
$在脚本中没有很好的定义,因为您还没有运行任何后台命令。@h3nrik
\u term
是一个字符串。引号只是保护任何特殊字符不受shell解释的影响;他们没有定义字符串。@chepner我修改了代码。它仍然不输出捕获的SIGTERM信号不要使用
kill-9
。这是用来杀死有缺陷的程序的,因为它不允许进程在自己之后清理。在这种情况下,sigterm或sigint可能更合适。当然,除非它们不是行为良好的进程,否则sigkill就是问题所在……因为它不能被忽略。