簡體   English   中英

如何從Perl腳本中捕獲系統命令的stdin和stdout?

[英]How can I capture the stdin and stdout of system command from a Perl script?

在Perl腳本的中間,有一個我想要執行的系統命令。 我有一個字符串,其中包含需要輸入stdin的數據(該命令只接受來自stdin的輸入),我需要捕獲寫入stdout的輸出。 我已經看過在Perl中執行系統命令的各種方法, open函數似乎是我需要的,除了它看起來我只能捕獲stdin或stdout,而不是兩者。

目前,似乎我最好的解決方案是將open ,redirect stdout用於臨時文件,並在命令完成后從文件中讀取。 有更好的解決方案嗎?

IPC :: Open2 / 3很好,但我發現通常我真正需要的只是IPC :: Run3 ,它可以很好地處理簡單的情況並且復雜度最低:

use IPC::Run3;    # Exports run3() by default

run3( \@cmd, \$in, \$out, \$err );

該文檔將IPC :: Run3與其他替代方案進行了比較。 即使您不決定使用它,也值得一讀。

IPC :: Open3可能會做你想要的。 它可以捕獲STDERR和STDOUT。

http://metacpan.org/pod/IPC::Open3

位於腳本頂部的某處,包含該行

use IPC::Open2;

這將包括必要的模塊,默認情況下通常安裝大多數Perl發行版。 (如果沒有它,可以使用CPAN安裝它。)然后,而不是打開,調用:

$pid = open2($cmd_out, $cmd_in, 'some cmd and args');

您可以通過將數據發送到$ cmd_in將數據發送到命令,然后通過從$ cmd_out讀取來讀取命令的輸出。

如果您還希望能夠讀取命令的stderr流,則可以使用IPC :: Open3模塊。

perlipc文檔涵蓋了許多方法,包括IPC :: Open2和IPC :: Open3。

我最近發現的一個非常簡單的方法是使用IPC :: Filter模塊 它可以讓您非常直觀地完成工作:

$output = filter $input, 'somecmd', '--with', 'various=args', '--etc';

注意如果你傳遞一個列表,它如何在不通過shell的情況下調用你的命令。 它還可以合理地處理常見實用程序的錯誤。 (失敗時,它會die ,使用STDERR中的文本作為錯誤消息;成功時,STDERR就會被丟棄。)

當然,它不適合大量數據,因為它無法進行任何流處理; 此外,錯誤處理可能不夠精細,無法滿足您的需求。 但它使許多簡單的案例非常簡單。

我想你想看看IPC :: Open2

有一個特殊的perl命令

open2()

更多信息可以在以下網址找到: http//sunsite.ualberta.ca/Documentation/Misc/perl-5.6.1/lib/IPC/Open2.html

如果我只想要一行輸出或想要將結果拆分為換行符以外的其他內容,我總是這樣做:

my $result = qx( command args 2>&1 );  
my $rc=$?;  
# $rc >> 8 is the exit code of the called program.

if ($rc != 0 ) {  
    error();  
}  

如果要處理多行響應,請將結果作為數組獲取:

my @lines = qx( command args 2>&1 );  

foreach ( my $line ) (@lines) {  
    if ( $line =~ /some pattern/ ) {  
        do_something();  
    }  
}  

如果您不想包含額外的包,您可以這樣做

open(TMP,">tmpfile");
print TMP  $tmpdata ;
open(RES,"$yourcommand|");
$res = "" ;
while(<RES>){
$res .= $_ ;
}

這與你的建議相反,但也應該有效。

暫無
暫無

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

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