在perl中使用chld信号处理程序时,即使使用system和backticks也会发送chld信号。但是对于系统和backticks子进程,wait和waitpid似乎都没有设置$?在suse 11 linux上的信号处理程序中。当chld信号处理程序处于活动状态时,有没有方法确定backtick命令的返回代码?
我为什么要这个?因为我想要叉子?然后启动一个中等长度的命令,然后调用一个Perl包,这个包需要很长时间才能产生一个答案(它使用反勾号执行外部命令,并检查返回的$?),并知道我的命令何时完成,以便我可以执行操作,例如启动第二个命令。(关于如何在不使用sigchld的情况下实现这一点的建议也很受欢迎)但是既然信号处理程序破坏了backtick$?值,则该包失败。
例子:

use warnings;
use strict;
use POSIX ":sys_wait_h";

sub reaper {
    my $signame = shift @_;
    while (1) {
       my $pid = waitpid(-1, WNOHANG);
       last if $pid <= 0;
       my $rc = $?;
       print "wait()=$pid, rc=$rc\n";
    }
}

$SIG{CHLD} = \&reaper;

# system can be made to work by not using $?, instead using system return value
my $rc = system("echo hello 1");
print "hello \$?=$?\n";
print "hello rc=$rc\n";

# But backticks, for when you need the output, cannot be made to work??
my @IO = `echo hello 2`;
print "hello \$?=$?\n";

exit 0;

在我可能尝试访问的所有位置生成-1返回代码:
hello 1
wait()=-1, rc=-1
hello $?=-1
hello rc=0
wait()=-1, rc=-1
hello $?=-1

所以我找不到任何地方可以访问backticks返回值。

最佳答案

这个问题已经困扰我好几天了。我相信有两种解决方案是必需的,这取决于你的背景。
如果子代码中有反勾号:
解决办法是把下面的线放在儿童叉里。我认为你上面的“如果我完全关闭了chld处理程序的反勾,那么如果孩子结束了,我可能不会得到信号”是不正确的。当孩子退出时,仍然会在父进程中得到回调,因为该信号仅在子内禁用。所以当孩子离开时,家长仍然会收到信号。只是当孩子的孩子(背板中的一部分)离开时,孩子就没有信号。
local $SIG{'CHLD'} = 'DEFAULT'
我不是Perl专家,我读到您应该将chld信号设置为字符串“ignore”,但这在我的情况下不起作用。从表面上看,我认为这可能是问题的根源。完全忽略这一点似乎也解决了这个问题,我想这与将其设置为默认值是一样的。
如果父代码中有反勾号:
将此行添加到reaper函数中:
local ($!, $?);
当你的代码在backticks中完成并且reaper正在设置$时,会调用reaper?通过赚$?本地不设置全局$?是的。

关于linux - Perl 5.8:使用SIGCHLD时,可以从反引号中获取任何返回码,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26898568/

10-09 12:36