从perl中的external*nix命令获取STDOUT,STDERR和响应代码

Gre*_*Dan 4 perl stdout stderr

我想从我的Perl脚本中执行外部命令,将stdout和stderr的输出放入$variable我的选择中,并将命令的退出代码放入$?变量中.

我在perlfaq8和他们的论坛中找到了解决方案,但他们并没有为我工作.奇怪的是,只要退出代码是正确的,我在任何情况下都不会获得sdterr的输出.

我在Red Hat Linux 5上使用Perl版本5.8.8.

这是我正在尝试的一个例子:

my $cmd="less";
my $out=`$cmd 2>&1`;
Run Code Online (Sandbox Code Playgroud)

要么

my $out=qx($cmd 2>&1);
Run Code Online (Sandbox Code Playgroud)

要么

open(PIPE, "$cmd 2>&1|");
Run Code Online (Sandbox Code Playgroud)

当命令成功运行时,我可以捕获stdout.

我不想使用其他捕获模块.如何捕获外部命令的完整结果?

Joe*_*ger 9

这正是David Golden写作时面临的挑战Capture::Tiny.我认为它可以帮助您完全满足您的需求.

基本示例:

#!/usr/bin/env perl

use strict;
use warnings;

use Capture::Tiny 'capture';

my ($stdout, $stderr, $return) = capture {
  system( 'echo Hello' );
};

print "STDOUT: $stdout\n";
print "STDERR: $stderr\n";
print "Return: $return\n";
Run Code Online (Sandbox Code Playgroud)

重读后你可能真的想把capture_mergedSTDOUT和STDERR加入到一个变量中,但是我给出的例子很好而且很通用,所以我会离开它.


JRF*_*son 5

STDERR旨在用于可能需要从STDOUT输出流中分离的错误或消息。因此,我不希望STDERR从像 之类的命令的输出中得到任何结果less

如果您想要两者(或其中一个)流和返回代码,您可以这样做:

my $out=qx($cmd 2>&1);
my $r_c=$?
print "output was $out\n";
print "return code = ", $r_c == -1 ? $r_c : $r_c>>8, "\n";
Run Code Online (Sandbox Code Playgroud)

如果该命令不可执行(可能是因为您本想使用lesslsss改为写入),则返回代码将为 -1。否则,正确的退出值是高 8 位。参见系统


小智 5

实际上,编写此代码的正确方法是:

#!/usr/bin/perl
$cmd = 'lsss';  
my $out=qx($cmd 2>&1);
my $r_c=$?;
print "output was $out\n";
print "return code = ", $r_c, "\n";
Run Code Online (Sandbox Code Playgroud)

如果没有错误,您将得到一个“ 0”,如果有错误,您将得到一个“ -1”。