linux - Perl 5.8 : possible to get any return code from backticks when SIGCHLD in use

标签 linux perl

当在 Perl 中使用 CHLD 信号处理程序时,即使使用系统和反引号也会发送 CHLD 信号。但是对于 system 和 backticks 子进程,wait 和 waitpid 似乎都没有设置 $?在 SuSE 11 linux 的信号处理程序中。当 CHLD 信号处理程序处于事件状态时,是否有任何方法来确定反引号命令的返回代码?

我为什么要这个?因为我想 fork (?)并启动一个中等长度的命令,然后调用一个需要很长时间才能产生答案的 perl 包(并且它使用反引号执行外部命令并在 $? 中检查它们的返回码),并且知道什么时候我的命令已完成,因此我可以采取行动,例如启动第二个命令。 (也欢迎提出如何在不使用 SIGCHLD 的情况下完成此操作的建议。)但是由于信号处理程序破坏了反引号 $?值,该包失败。

例子:

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

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

最佳答案

同样的问题已经困扰我好几天了。我相信根据反引号的位置,需要 2 种解决方案。

如果您在子代码中有反引号:

解决方案是将下面的行放在子叉中。我认为您上面的陈述“如果我完全关闭反引号周围的 CHLD 处理程序,那么如果 child 结束,我可能不会收到信号”是不正确的。当 child 退出时,您仍然会在 parent 中获得回调,因为信号仅在 child 内部被禁用。因此,当 child 退出时, parent 仍然会收到信号。只是当 child 的 child (反引号中的部分)退出时, child 没有收到信号。

本地 $SIG{'CHLD'} = 'DEFAULT'

我不是 Perl 专家,我读到过您应该将 CHLD 信号设置为字符串“IGNORE”,但这在我的情况下不起作用。从表面上看,我相信这可能是导致问题的原因。完全保留它似乎也解决了我认为与将其设置为 DEFAULT 相同的问题。

如果父代码中有反引号:

将此行添加到您的收割器函数中: 本地 ($!, $?);

当反引号内的代码完成并且收割者正在设置 $? 时,正在发生的事情是收割者被调用。通过赚取美元?本地它不设置全局 $?。

关于linux - Perl 5.8 : possible to get any return code from backticks when SIGCHLD in use,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26898568/

相关文章:

linux - 恢复格式化分区

c - 用C读写二进制文件?

perl - 如何决定是否使用 Perl CGI 与常规 HTML 输出

mysql - 升级到 5.8.8 后 Perl 脚本损坏

perl - 我可以在 Chart::Gnuplot (Perl) 中填充绘图吗?

linux - VIM 使用系统剪贴板

c++ - ACE Reactor 在系统调用中断时退出

mysql - 每 n 秒自动从数据库中删除过时的行

perl - 如何优雅地调用名称保存在变量中的 Perl 子例程?

linux - 给用户 sudo 访问 perl 的权限是不是一个坏主意?