Perl:使用IPC :: Run进行I / O重定向

时间:2014-01-15 04:30:54

标签: perl io openssl ipc

使用IPC::Run试图模仿以下内容并不会对我产生预期的影响。不幸的是,我不熟悉I /)重定向IPC::Run为自己解决,我需要运用SO的知识库。

命令我正在模仿

echo | openssl s_client -connect google.com:443 2>/dev/null |openssl x509

这将显示从openssl的远程服务器检索到的SSL证书。它工作正常的关键是2>/dev/null stderr泵到/ dev / null,因为openssl将使用stderr输出其他信息(不是真正的错误)而没有这个传送到openssl x509的命令将失败。

以下是IPC::Run的用法。我需要使用openssl在perl中使用IPC::Run的此功能,因为这是我目前正在使用的所有其他功能。不幸的是,使用IPC::Run以我的shell重定向(例如2>/dev/null)的方式不起作用,因为运行命令并添加2>/dev/null只会将其作为openssl电话的参数。

目前我有以下内容,可以在没有令人讨厌的stderr问题的情况下运行。此外,没有同意openssl命令来禁止它。

use IPC::Run qw( run );    
my ( $out, $err );
    my @cmd  = qw(echo);                                            
    my @cmd2 = qw(openssl s_client -connect google.com:443:443);     
    my @cmd3 = qw(openssl x509);                                   
    run \@cmd, "|", \@cmd2, "|", \@cmd3, \$out, \$err;                        
    if ( $err ne '' ) {                                              
        print $err;
    }
    else {
        print "$out\n";
    }

所以基本上我需要为@ cmd2丢弃stderr,这通常是用,

run \@cmd, \$in, \$out, \undef;

但是与|对于@ cmd3显示为stdin我无法从@ cmd2重定向stderr,因为stderr的描述符位于stdout之后。我认为必须有一种方法可以在两个管道之间使用这个模块来抑制'stderr',但是我还没有想到它,并且我不熟悉I / O操作,足以快速得到它。有人建议从经验中做到这一点吗?

1 个答案:

答案 0 :(得分:3)

不需要'回音'。如果您只想关闭由s_client打开的连接,请使用关闭的stdin。 另外在你的例子中你连接到google.com:443:443,这是可以支持的:443太多了。 以下适用于我

use IPC::Run 'run';

my @cmd1 = qw(openssl s_client -connect google.com:443);
my @cmd2 = qw(openssl x509);

my $stdout = my $stderr = '';
run \@cmd1, '<', \undef, '|', \@cmd2, '2>', \$stderr, '>', \$stdout;
print $stdout;