为什么我的 fork/exec 和关闭会丢失 child 的错误代码

How come my fork/exec and close is losing the error code from the child

我有一段perl代码,大致是这样的

my $pid = open(PIPE, '-|');
die "Unable to fork: $!\n" if !defined $pid;
if ($pid == 0)
{
    open STDERR, '>&STDOUT' or die "Can't redirect STDERR to STDOUT\n";
    exec(@cmd);
    die "Unexpected exec failure: $!\n";
}
my @lines = (<PIPE>);
close PIPE;
if ($? != 0) { do stuff; }

但是,由于我无法理解的原因,可能与实际调用的程序不存在有关,有时这无法从 $?[=18 中的 child 中提取错误=]

@lines 包含预期的 "Unexpected exec failure: File or directory does not exist"(以及 $SIG{__DIE__} 处理程序的一些其他输出),但 $? 设置为 0。我正在努力现在还可以通过检查 close 中的 return 幸运地设置为 1。但是我的错误代码去哪儿了?

我不知道。它不应该发生。您可以改用以下内容:

use IPC::Open qw( open3 );

my $pid = open3(local *PIPE, '>&STDOUT', undef, @cmd);
while (<PIPE>) {
   ...
}

waitpid($pid, 0);

奖励:启动子进程时发生的错误(例如来自重复或 exec 的错误)会在 父进程 中抛出异常,因此它不会看起来不像命令 运行 并返回错误。

嗯,我找到了。

有人在库中添加了一个 END{} 块,它正在破坏 return 代码(通过调用系统并因此破坏 $?)。我取消了更改,一切都很顺利。