加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

bash – 使用SIGINT默认处理程序时从system()返回值

发布时间:2020-12-15 21:19:04 所属栏目:安全 来源:网络整理
导读:当子进程从终端接收到SIGINT时,我遇到来自system()的一些奇怪的返回值.为了解释,从Perl脚本parent.pl我使用system()来运行另一个Perl脚本作为子进程,但我还需要通过 shell运行子进程,所以我使用系统’sh’,’ – c’,… form ..所以孩子的父母成了sh进程,sh
当子进程从终端接收到SIGINT时,我遇到来自system()的一些奇怪的返回值.为了解释,从Perl脚本parent.pl我使用system()来运行另一个Perl脚本作为子进程,但我还需要通过 shell运行子进程,所以我使用系统’sh’,’ – c’,… form ..所以孩子的父母成了sh进程,sh进程的父成为parent.pl.另外,为了避免sh进程接收到SIGINT信号,我把它困住了.

例如,parent.pl:

use feature qw(say);
use strict;
use warnings;

for (1..3) {
    my $res = system 'sh','-c',"trap '' INT; child$_.pl";
    say "Parent received return value: " . ($res >> 8);
}

其中child1.pl:

local $SIG{INT} = "DEFAULT";
sleep 10;
say "Child timed out..";
exit 1;

child2.pl:

local $SIG{INT} = sub { die };
sleep 10;
say "Child timed out..";
exit 1;

和child3.pl是:

eval {
    local $SIG{INT} = sub { die };
    sleep 10;
};
if ( $@ ) {
    print $@;
    exit 2;
}
say "Child timed out..";
exit 0;

如果我运行parent.pl(从命令行)并按CTRL-C中止每个子进程,则输出为:

^CParent received return value: 130
^CDied at ./child2.pl line 7.
Parent received return value: 4
^CDied at ./child3.pl line 8.
Parent received return value: 2

现在,我想知道为什么我得到案例1的返回值130,案例2的返回值为4.

此外,在这种情况下确切地知道“DEFAULT”信号处理程序的作用会很好.

注意:如果我用shash替换sh(并且在bash中使用陷阱SIGINT而不是INT),则返回相同的值.

也可以看看:

> Propagation of signal to parent when using system
> perlipc
>第15章,Programming Perl,4th Edition

解决方法

这个问题与您之前提到的 Propagation of signal to parent when using system非常相似.

从我的bash文档:

When a command terminates on a fatal signal N,bash uses the value of 128+N as the exit status.

SIGINT通常是2,所以128 2给你130.

Perl的die通过检查$来计算其退出代码!还是$?对于未捕获的异常(因此,不是您使用eval的情况):

exit $! if $!;              # errno
exit $? >> 8 if $? >> 8;    # child exit status
exit 255;                   # last resort

请注意,在这种情况下,Perl以原样退出,而不是向上移位8位.

errno值恰好是4(见errno.h). $!变量是具有不同字符串和数值的dualvar.以数字方式使用它(如添加零)以获得数字方面:

use v5.10;

local $SIG{INT}=sub{
    say "numeric errno is ",$!+0;
    die
    };
sleep 10;
print q(timed out);
exit 1;

这打印:

$bash -c "perl errno.pl"
^Cnumeric errno is 4
Died at errno.pl line 6.
$echo $?
4

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读