首页 文章

使用Perl IPC :: Open3捕获输出,错误和退出代码在较新的Perl中失败

提问于
浏览
1

我有一个小子程序,使用IPC::Open3(通常我使用Capture::Tiny)因为我只想使用核心Perl模块 . 此子例程是较大安装脚本的一部分 . 它捕获命令输出,错误和退出代码 . 它适用于带有Perl 5.10.1(IPC :: Open3 1.04)的Centos 6(和5),但它在使用Perl 5.18.1(IPC :: Open3 1.13)的Ubuntu 14 LTS上失败 . 有人可以向我解释为什么它在新的Perl上失败以及如何修复它 .

sub _capture_output {
    croak( '_capture_output() needs a $cmd and options' ) unless (@_ ==  2);
    my ($cmd, $param_href) = @_;

    my $verbose = defined $param_href->{verbose}  ? $param_href->{verbose}  : 0;   #default is silent
    print "Report: COMMAND is: $cmd\n" if $verbose;

    local $| = 1;   #autoflush
    my ( $in, $out, $err );
    open my ($in_fh),  '<', \$in;
    open my ($out_fh), '>>', \$out;
    open my ($err_fh), '>>', \$err;

    my $pid = open3($in_fh, $out_fh, $err_fh, $cmd);

    my $stdout = $out;
    my $stderr = $err;
    $stdout = '' if !defined $stdout;
    $stderr = '' if !defined $stderr;

    waitpid( $pid, 0 ) or die "$!\n";
    my $exit =  $? >> 8;

    if ($verbose == 2) {
        print 'STDOUT is: ', "$stdout", "\n", 'STDERR  is: ', "$stderr", "\n", 'EXIT   is: ', "$exit\n";
    }

    return  $stdout, $stderr, $exit;
}

它失败了open3调用错误:

Report: COMMAND is: plenv --version
Uncaught exception from user code:
open3: exec of plenv --version failed at ./Perlinstall.pm line 175.
IPC::Open3::_open3('open3', 'GLOB(0x27819a0)', 'GLOB(0x2781730)', 'GLOB(0x2781b68)', 'plenv --version') called at /usr/share/perl/5.18/IPC/Open3.pm line 250

当我在命令行上尝试此命令时,我得到相同的错误代码但不同的错误 . Centos6:

$ plenv --version
-bash: plenv: command not found
$ echo $?
127

Ubuntu14:

$ plenv --version
No command 'plenv' found, did you mean:
Command 'p7env' from package 'libnss3-tools' (main)
plenv: command not found
$ echo $?
127

1 回答

  • 4

    目前尚不清楚您认为问题是什么,但 open3 的行为与记录有关 .

    它不会在失败时返回:它只会引发匹配/ ^ open3:/的异常 .

    您尝试执行的程序不存在,因此 open3 会抛出异常 . 我想你想知道为什么没有设置 $? 以及为什么没有打印到 $stderr 中的句柄,但这不应该是一个惊喜,因为该程序从未运行过 .

    请记住 exec (由 open3 使用)将绕过shell,如果命令是一个除了空格之外没有shell字符的字符串,那么你将得到与执行不同的结果

    plenv --version         
    # Same as: open3(..., ..., ..., 'plenv', '--version')
    # Exception: Can't find plenv
    

    plenv '--version'
    # Same as: open3(..., ..., ..., '/bin/sh', '-c', q{plenv '--version'})
    # Shell exits with an error in ($? >> 8)
    

    您可以使用 eval BLOCK 捕获异常 .

相关问题