Linux 为什么可以';在脚本中启用作业控制时,我是否捕获进程信号?
当我在shell脚本中启用作业控制时(使用Linux 为什么可以';在脚本中启用作业控制时,我是否捕获进程信号?,linux,bash,shell,Linux,Bash,Shell,当我在shell脚本中启用作业控制时(使用set-m),我不再能够捕获进程信号。请看下面的代码: #!/bin/bash set -m for i in `seq 15`; do trap 'echo " Signal $i catched"' $i done while true; do echo " Waiting for a process signal" sleep 999 done 当我运行上述代码并按下例如Ctrl+C时,不会发生任何事情: Waiti
set-m
),我不再能够捕获进程信号。请看下面的代码:
#!/bin/bash
set -m
for i in `seq 15`; do
trap 'echo " Signal $i catched"' $i
done
while true; do
echo " Waiting for a process signal"
sleep 999
done
当我运行上述代码并按下例如Ctrl+C时,不会发生任何事情:
Waiting for a process signal
^CWaiting for a process signal
但是,当我运行相同的代码删除set-m
时,我确实得到了一个答案:
Waiting for a process signal
^C Signal 15 catched
我的问题是:
注意:并非所有进程都会发生这种情况,如果我使用
read
而不是sleep
,它确实有效。解决方案是将sleep放在后台,并使用bash内置的wait
在睡眠完成时等待。因此,请尝试以下方法:
#!/bin/bash
set -m
for i in `seq 15`; do
trap 'echo " Signal $i catched"' $i
done
while true; do
echo " Waiting for a process signal"
sleep 999 & wait $!
done
样本运行:
$ bash script
Waiting for a process signal
^C Signal 15 catched
Waiting for a process signal
^C Signal 15 catched
Waiting for a process signal
有关更多详细信息,请参阅。为什么首先要在脚本中启用作业控制?作业控制通过在不同于shell的进程组中运行外部程序来工作。键盘信号只发送到前台进程组,当程序运行时,shell不在前台组中。@Barmar在某些情况下,作业控制在脚本中很有用。例如,当我在后台启动一个新流程时,如果我将来需要杀死整个流程组,我将无法这样做。因为,当未启用作业控制时,不会创建新的进程组,所有创建的进程都将属于当前组。使此解决方案更好的是,它不仅可以完美地工作,而且可以与任何调用的程序一起工作。因为,无论调用什么程序,它都将放在后台,
wait
将在前台捕获所有信号。