2015-11-10 37 views
4

在Perl中,讀取子進程的標準輸出的方法是使用open如何在面向對象的Perl子進程讀取標準輸出

open(PIPE, "ls -l |"); 

我一直在尋找一個更加面向對象的方式來儘管如此,我一直在使用IO::Pipe,並取得了一些成功。不過,我想檢測錯誤,特別是如果該命令不可執行。不過,我不知道如何通過IO::Pipe來做到這一點。下面是我有:

use strict; 
use warnings; 

use IO::Pipe; 


my($cmd) = join (" ", @ARGV); 

open(PIPE, "$cmd |") || die qq(error opening PIPE); 
while (<PIPE>) { 
     chomp; 
     print "DBG1: $_\n"; 
} 

close PIPE; 

my($pipe) = IO::Pipe->new(); 
$pipe->reader($cmd); 
die qq(error opening IO::Pipe) if $pipe->eof(); 

while (<$pipe>) { 
     chomp; 
     print "DBG2: $_\n"; 
} 

$pipe->close(); 

如果子進程的命令是無效的,這兩個檢查將正確die。如果子過程中不產生輸出,不過,eof()會報告錯誤,即使命令本身是好的:

$ perl pipe.pl "ls -l >/dev/null" 
error opening IO::Pipe at pipe.pl line 20. 

一大堆的問題,然後:

是否有一個合理的面向對象的方法從Perl中的子進程讀取?是IO::Pipe正確的工具使用?如果是這樣,我該如何檢查以確保子流程命令已成功創建?如果不是,我應該使用什麼?我不想寫入子流程,所以我不認爲我想要IPC::Open2IPC::Open3。如果可能,我寧願使用核心模塊。

回答

0

Backticks不是一個核心模塊,但似乎做你的期望。

use strict; 
use warnings; 
use Backticks; 
my $cmd = Backticks->new(join (" ", @ARGV)); 
$cmd->run(); 

if ($cmd->success){ 
     print $cmd->stdout 
} else { 
     print "Command failed\n"; 
} 

有一個有效的命令運行此則無效命令給出如下結果

io_pipe.pl 「UNAME -o」

GNU/Linux 

io_pipe.pl 「UNAME -z」

Command failed 

更新 正如@thisSuitIsNotBlack指出的那樣,此模塊更改了perl中反引號的deafult行爲。您應該閱讀POD的註釋部分。然而,主要應該注意的是:

由Filter :: Simple提供的最重要的backticks。來源 過濾可奇怪的,有時...如果你想使用這個模塊中 一個純粹的傳統的Perl OO風格,只是儘快關閉源 過濾爲您加載模塊:

use Backticks; 
no Backticks; 
+1

默認情況下,反引用會使用[源過濾](https://metacpan.org/pod/Backticks#Source-filtering)覆蓋'\'\''的行爲。我會禁用此,因爲[源過濾器通常是不好的](http://stackoverflow.com/questions/1785852/why-are-perl-source-filters-bad-and-when-is-it-ok-to-使用它們)。文檔建議'使用反引號;沒有Backticks;',儘管我仍然試圖圍繞如何工作。 – ThisSuitIsBlackNot

+0

@ThisSuitIsBlackNot - 是的,我注意到在POD和各種恢復perl反引號功能的方式,但讓用戶自己閱讀POD。我假設他是否想要使用更多的面向對象的方法來調用外部命令,他會這麼做 –

+0

我的觀點是,你的示例代碼改變了核心操作符的行爲,但沒有表明它是這樣做的。我認爲,在你的答案(或代碼本身)的文本中提到的是權證,而不是隱藏在鏈接中。 – ThisSuitIsBlackNot

3

問題不是IO ::管道。問題是eof是檢查管道錯誤的錯誤方法。這並不意味着沒有管道,這意味着沒有什麼可以從管道讀取。你會遇到與eof PIPE相同的問題。子流程不打印任何東西是完全正確的。

如果您想檢查子進程是否成功運行,那麼事實證明IO :: Pipe已經爲您執行了該操作。

# IO::Pipe: Cannot exec: No such file or directory 
$pipe->reader("hajlalglagl"); 
相關問題