从您的交互式终端中,perl进程杀死它所属的进程组。 (shell在自己的进程组中运行perl。)外壳报告这个不寻常的终止在$?
:
t0 interactive shell (pid=123, pgrp=123)
|
t1 +------> perl -e (pid=456, pgrp=456, parent=123)
| |
t2 (wait) kill(-2, 456) (in perl, same as kill pgrp 456 w/ SIGINT)
| |
t3 (wait) *SIGINT*
|
t4 report $?
从你shell脚本,perl的进程杀死(可能)不存在程序组,然后成功退出。您的交互式shell创建一个新的进程组来运行您的shell脚本,然后该脚本在同一个进程组中作为子进程运行perl。
t0 shell (pid=123, pgrp=123)
|
t1 +-------> shell:1.sh (pid=456, pgrp=456, parent=123)
| |
t2 (wait) +-------------> perl -e (pid=789, pgrp=456, parent=456)
| | |
t3 (wait) (wait) kill pgrp 789 with SIGINT (error: no such pgrp)
| | |
t4 (wait) (wait) exit success
| |
t5 (wait) exit success
|
t6 report $?
在你backticked(qx//
)例如,你的交互shell启动一个新的进程组一个shell进程。 (这里并不重要,但该进程在同一个进程组中运行perl。)然后,Perl以自己的孩子身份运行系统kill
命令,,其语义不同于perl kill
的语义。这个grandchild命令直接发送一个SIGINT给perl PID,而不是一个SIGINT给一个进程组。 Perl终止,并且退出代码作为脚本的退出代码传递,因为它是脚本中的最后一个命令。
该图是比以前的忙一点:
t0 shell (pid=123, pgrp=123)
|
t1 +-------> shell:2.sh (pid=456, pgrp=456, parent=123)
| |
t2 (wait) +----------> perl -e (pid=789, pgrp=456, parent=456)
| | |
t3 (wait) (wait) +---------> /bin/kill SIGINT 789
| | | |
t4 (wait) (wait) *SIGINT* exit success
| |
t5 (wait) return $?
|
t6 report $?
顺便说,'杀INT => - $$'是一个更好的写入'杀-2,$$'的方式。 – ikegami