从终端运行时,以下代码的行为符合预期:
perl -e 'kill -2, $$; warn HERE, $/'
它向自己发送SIGINT
并在到达“HERE”之前死亡:
~# perl -e 'kill -2, $$; warn HERE, $/'
~# echo $?
130
~#
问题:从 shell 脚本运行时,相同的代码无法杀死自身 PID:
~# cat 1.sh
perl -e 'kill -2, $$; warn HERE, $/'
~#
~# sh 1.sh
HERE
~#
~# echo $?
0
~#
另一方面,用 shell 的 kill
替换 perl 的 kill
就可以了:
~# cat 2.sh
perl -e 'qx/kill -2 $$/; warn HERE, $/'
~#
~# sh 2.sh
~#
~# echo $?
130
~#
不太明白这里发生了什么,请帮忙..
最佳答案
首先,
kill -2, $$
最好写成
kill 2, -$$
更好的选择是
kill INT => -$$
这些发送SIGINT
到指定的进程组。
您的主要问题似乎是为什么两个 shell 的行为不同。本节对此进行了解释。
进程组代表一个应用程序。
当您从交互式 shell 启动程序时,它不是较大应用程序的一部分,因此 shell 会为该程序创建一个新的进程组。
但是,由脚本(即非交互式 shell)创建的进程与脚本本身属于同一应用程序,因此 shell 不会为它们创建新的进程组。
您可以使用以下方式将其可视化:
sh -i <<< 'perl -e '\''system ps => -o => "pid,ppid,pgrp,comm"'\'''
输出以下内容:$ perl -e 'system ps => -o => "pid,ppid,pgrp,comm"' PID PPID PGRP COMMAND 8179 8171 8179 bash 14654 8179 14654 sh 14655 14654 14655 perl 14656 14655 14655 ps $ exit
在交互模式下,
perl
位于perl
的头部和ps
的节目组。sh <<< 'perl -e '\''system ps => -o => "pid,ppid,pgrp,comm"'\'''
输出以下内容:PID PPID PGRP COMMAND 8179 8171 8179 bash 14584 8179 14584 sh 14585 14584 14584 perl 14586 14585 14584 ps
在非交互模式下,
sh
位于perl
的头部和ps
的节目组。
您的失败是由于未将信号发送到进程组的头部(即应用程序)而导致的。如果您检查过,错误 kill
报告为ESRCH
(“没有这样的过程”)。
ESRCH
The pid or process group does not exist. [...]
杀死当前进程的进程组,替换不合适的
kill INT => -$$ # XXX
与
kill INT => -getpgrp() # Kill the application
<小时/>
您可以将您的perl
通过简单地调用以下命令来获取其自己的进程组的头:
setpgrp();
测试:
$ sh <<< 'perl -e '\''system ps => ( -o => "pid,ppid,pgrp,comm" )'\'''
PID PPID PGRP COMMAND
8179 8171 8179 bash
16325 8179 16325 sh
16326 16325 16325 perl
16327 16326 16325 ps
$ sh <<< 'perl -e '\''setpgrp(); system ps => ( -o => "pid,ppid,pgrp,comm" )'\'''
PID PPID PGRP COMMAND
8179 8171 8179 bash
16349 8179 16349 sh
16350 16349 16350 perl
16351 16350 16350 ps
这不是您通常想做的事情。
<小时/>最后是Perl代码
kill INT => -$pgrp
相当于以下调用kill
命令行实用程序:
kill -s INT -$pgrp
kill -INT -$pgrp
kill -2 -$pgrp
您失踪了-
在你的qx//
程序,因此它向已识别的进程而不是已识别的程序组发送 SIGINT。
关于从 bash 脚本运行时,Perl 无法杀死 self pid,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43845000/