使用SIGINT默认处理程序时,从system()返回值 [英] Return value from system() when using SIGINT default handler
问题描述
当子进程从终端接收到SIGINT时,我正在经历 system()
的一些奇怪的返回值.为了说明,从Perl脚本 parent.pl
中,我使用 system()
来运行另一个Perl脚本作为子进程,但是我还需要通过外壳来运行该子进程.,所以我使用了 system'sh','-c',...
形式.因此,子代的父代成为了 sh
进程,而子代的父代成为了 sh
进程. sh
进程变为 parent.pl
.另外,为了避免 sh
进程接收到 SIGINT
信号,我将其捕获.
I am experiencing some strange return values from system()
when a child process receives a SIGINT from the terminal. To explain, from a Perl script parent.pl
I used system()
to run another Perl script as a child process, but I also needed to run the child through the shell, so I used the system 'sh', '-c', ...
form.. So the parent of the child became the sh
process and the parent of the sh
process became parent.pl
. Also, to avoid having the sh
process receiving the SIGINT
signal, I trapped it.
例如, 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中止每个子进程,则输出为:
If I run parent.pl
(from the command line) and press CTRL-C to abort each child process, the output is:
^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.
Now, I would like to know why I get a return value of 130 for case 1, and a return value of 4 for case 2.
此外,很高兴知道在这种情况下"DEFAULT"
信号处理程序的作用.
Also, it would be nice to know exactly what the "DEFAULT"
signal handler does in this case.
注意:如果我将 sh
替换为 bash
(并捕获 SIGINT
而不是 INT
,则会返回相同的值>在 bash
中).
Note: the same values are returned if I replace sh
with bash
( and trap SIGINT
instead of INT
in bash
).
另请参阅:
推荐答案
此问题与在使用时向父级传播信号非常相似系统,您之前曾问过.
This question is very similar to Propagation of signal to parent when using system that you asked earlier.
来自我的bash文档:
From my bash docs:
当命令在致命信号N上终止时,bash将使用128 + N的值作为退出状态.
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.
SIGINT is typically 2, so 128 + 2 give you 130.
Perl的 die 通过检查 $!找出其退出代码!/code>或
$?
来捕获未捕获的异常(因此,使用 eval
的情况并非如此):
Perl's die figures out its exit code by inspecting $!
or $?
for an uncaught exception (so, not the case where you use eval
):
exit $! if $!; # errno
exit $? >> 8 if $? >> 8; # child exit status
exit 255; # last resort
请注意,在这种情况下,Perl会以原样的值退出,而不会上移8位.
Notice that in this case, Perl exits with the value as is, not shifted up 8 bits.
errno值恰好为4(请参见 errno.h ). $!
变量是具有不同字符串和数字值的对偶变量.以数字方式使用它(如加零)以获取数字面:
The errno value happens to be 4 (see errno.h). The $!
variable is a dualvar with different string and numeric values. Use it numerically (like adding zero) to get the number side:
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
这篇关于使用SIGINT默认处理程序时,从system()返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!