gpt4 book ai didi

从 bash 脚本运行时,Perl 无法杀死 self pid

转载 作者:行者123 更新时间:2023-12-02 08:25:34 25 4
gpt4 key购买 nike

从终端运行时,以下代码的行为符合预期:

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com