簡體   English   中英

從Perl中的外部* nix命令獲取STDOUT,STDERR和響應代碼

[英]Getting STDOUT, STDERR, and response code from external *nix command in perl

我想從我的Perl腳本中執行一個外部命令,將stdout和stderr的輸出都放入我選擇的$variable中,並將命令的退出代碼放入$? 變量。

我在perlfaq8及其論壇中瀏覽了解決方案,但它們對我不起作用。 奇怪的是,只要退出代碼正確,無論如何我都不會獲得sdterr的輸出。

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

這是我正在嘗試的示例:

my $cmd="less";
my $out=`$cmd 2>&1`;

要么

my $out=qx($cmd 2>&1);

要么

open(PIPE, "$cmd 2>&1|");

命令成功運行后,我可以捕獲標准輸出。

我不想使用其他捕獲模塊。 如何捕獲外部命令的全部結果?

這正是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";

重讀之后,您實際上可能希望將capture_merged將STDOUT和STDERR合並到一個變量中,但是我給出的示例很好且通用,因此我將其保留。

實際上,編寫此代碼的正確方法是:

#!/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";

如果沒有錯誤,您將得到“ 0”,如果有錯誤,您將得到“ -1”。

STDERR旨在用於可能需要與STDOUT輸出流分離的錯誤或消息。 因此,我不會期望less命令的輸出產生任何STDERR

如果您想要流(或其中一個)和返回碼,則可以執行以下操作:

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";

如果該命令不是可執行文件(也許是因為你想用的less ,但寫lsss代替),返回碼將是-1。 否則,正確的退出值是高8位。 參見system

這個問題的常見答案是使用包含外殼類型重定向的命令行。 但是,假設您要避免這種情況,並在命令和參數列表中使用open(),因此您不必擔心shell如何解釋輸入(它可能部分由用戶提供的值組成)。 然后,不使用諸如IPC :: Open3之類的包,則以下內容將同時讀取stdout和stderr:

my ($child_pid, $child_rc);

unless ($child_pid = open(OUTPUT, '-|')) {
  open(STDERR, ">&STDOUT");
  exec('program', 'with', 'arguments');
  die "ERROR: Could not execute program: $!";
}
waitpid($child_pid, 0);
$child_rc = $? >> 8;

while (<OUTPUT>) {
  # Do something with it
}
close(OUTPUT);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM