SIGALRM是否等待子shell进程?
以下是意外情况:在以下脚本中,SIGALRM是否等待子shell进程?,shell,signals,Shell,Signals,以下是意外情况:在以下脚本中,SIGALRM未在预期时间调用函数alarm() #!/bin/sh -x alarm() { echo "alarmed!!!" } trap alarm 14 OUTER=$(exec sh -c 'echo $PPID') #for arg in `ls $0`; do ls $0 | while read arg; do INNER=$(exec sh -c 'echo $PPID') # child A, the timer sle
SIGALRM
未在预期时间调用函数alarm()
#!/bin/sh -x
alarm() {
echo "alarmed!!!"
}
trap alarm 14
OUTER=$(exec sh -c 'echo $PPID')
#for arg in `ls $0`; do
ls $0 | while read arg; do
INNER=$(exec sh -c 'echo $PPID')
# child A, the timer
sleep 1 && kill -s 14 $$ &
# child B, some other scripts
sleep 60 &
wait $!
done
期望值:
1秒后,应调用函数alarm()
实际上:
alarm()
将一直被调用,直到60秒,或者当我们按Ctrl+C时
我们知道在脚本中,$$
实际上指示外部
过程,因此我想我们应该在1秒后看到字符串打印到屏幕上。然而,直到子B退出,我们才看到调用了alarm()
当我们对trap
行进行注释时,整个程序仅在1秒后终止。所以我想至少收到了SIGALRM
,但为什么它不调用操作呢
另外,作为一个附带问题,
SIGALRM
的默认行为是终止吗?从中,我被告知默认情况下会忽略它,那么为什么OUTER
在收到它后退出?从bash
手册页:
如果bash正在等待命令完成并接收到已设置陷阱的信号,则陷阱将
在命令完成之前不能执行。当bash通过wait等待异步命令时
内置,接收已设置陷阱的信号将导致等待内置立即返回
退出状态大于128,紧接着执行陷阱
您的原始脚本位于第一个场景中。子shell(while read循环)调用了
wait
,但顶层脚本只是在等待子shell,因此当它接收到信号时,陷阱在子shell完成之前不会执行。如果您使用kill-s14$INNER
向子shell发送信号,您将获得预期的行为。来自bash
手册页:
如果bash正在等待命令完成并接收到已设置陷阱的信号,则陷阱将
在命令完成之前不能执行。当bash通过wait等待异步命令时
内置,接收已设置陷阱的信号将导致等待内置立即返回
退出状态大于128,紧接着执行陷阱
您的原始脚本位于第一个场景中。子shell(while read循环)调用了
wait
,但顶层脚本只是在等待子shell,因此当它接收到信号时,陷阱在子shell完成之前不会执行。如果您使用kill-s14$INNER
将信号发送到子shell,您将获得预期的行为。您使用此程序的实际目标是什么?@JohnZwinck我的实际目标是创建两个子进程并相互控制:如果第二个子进程超时,第一个子进程将向主进程发送sigallarm以杀死第二个子进程;如果第一个孩子退出,第二个孩子将杀死第一个孩子。实际上,我已经完成了目标,但在这里,我试图在测试期间重现一个意外情况。我看到您有sleep 60&
。。你怎么知道这不是在休眠这个进程?@Bill抱歉,我们这里实际上有4个进程,那么你这么说是什么意思?我的意思是当你有sleep 60&
时,当前进程(即你的shell脚本)将休眠60秒。我不知道你是怎么说睡眠会让其他脚本进入睡眠状态的。这个程序的实际目标是什么?@JohnZwinck我的实际目标是创建两个子进程并相互控制:如果第二个子进程超时,第一个子进程将向主进程发送sigallarm以杀死第二个子进程;如果第一个孩子退出,第二个孩子将杀死第一个孩子。实际上,我已经完成了目标,但在这里,我试图在测试期间重现一个意外情况。我看到您有sleep 60&
。。你怎么知道这不是在休眠这个进程?@Bill抱歉,我们这里实际上有4个进程,那么你这么说是什么意思?我的意思是当你有sleep 60&
时,当前进程(即你的shell脚本)将休眠60秒。我不知道你是怎么说睡眠会让其他脚本进入睡眠状态的。真有趣!所以是等待
做了坏事?嗯,当我用for循环替换while循环(代码中的注释)时,我想父shell也应该被wait
和ignore报警信号阻塞?为什么此时事情会按预期进行?当您使用for循环时(我假设您的意思是for x in$0;…
),父对象(即接收信号的shell)正在调用wait
,因此第二句话适用并且wait
立即返回。有趣!所以是等待
做了坏事?嗯,当我用for循环替换while循环(代码中的注释)时,我想父shell也应该被wait
和ignore报警信号阻塞?为什么此时事情会按预期进行?当您使用for循环时(我假设您的意思是for x in$0;…
),父对象(即接收信号的shell)正在调用wait
,因此第二句话适用并且wait
立即返回。