[英]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.