2013-02-04 52 views
0

我有一個腳本,它在Expect中使用system()來執行不同的命令。從sytem()調用過濾STDOUT並輸出選擇性文本

對於大多數這些我不需要將STDOUT打印到用戶,但在一種情況下,我只想輸出的一小部分打印給用戶。我已經使用下面的方法來重定向STDOUT等所有不同的命令。

我的問題很簡單,我怎樣才能改變這種做法,我可以收集輸出的一些變量,打印只是一部分的所有輸出(字符串例如「組號= 12345)的用戶?

sub execute_cmd { 
my ($q) = @_; 
my $para1 = $q->param('para1'); 
my $para2 = $q->param('para2'); 
my $para3 = $q->param('para3'); 
if($transtype eq "A") { 
my $cmd = "\/\*ID\=66\*\/OOO LOIPAW\:XXX\=1\,ABC=K\'$para1\,DEF\=ALL\,GHI\=JKLMNO\,PQR\=$para2\;\r"; 
print $cmd;  
print "<br><br>"; 
open (TEMPERR, ">&STDERR"); 
open (TEMPOUT, ">&STDOUT"); 
open (STDERR, ">nul"); 
open (STDOUT, ">nul"); 
system ("./xxx.exp", $cmd); 
open (STDERR, ">&TEMPERR"); 
open (STDOUT, ">&TEMPOUT"); 
close (TEMPERR); 
close (TEMPOUT); 
} 
+0

你說的是系統命令的輸出嗎? – TLP

+0

是的。在系統輸出(「./xxx.exp」,$ cmd); –

+3

你也應該知道這段代碼看起來非常不安全。您在系統調用中直接使用CGI參數,而沒有任何形式的驗證。如果有人進入' rm -rf /'在你的「para2」參數中? – TLP

回答

1

你不需要做花哨OUT/ERR重定向,以消除由system()調用執行的命令的所有輸出

只需使用shell重定向:

system ("./xxx.exp $cmd > /dev/null"); # Get rid of STDOUT 

system ("./xxx.exp $cmd > /dev/null 2>&1"); # Get rid of STDOUT AND STDERR 

現在,捕獲輸出,你有兩個選擇:

  1. 使用反引號(或qx()運營商)

    my $stdout = qx#./xxx.exp $cmd#; 
    
  2. 重定向到一個文件,啜食文件中:

    我$ out_filename =「./something.out」; system(「./xxx.exp $ cmd> $ out_filename 2> & 1」); #捕獲STDOUT和STDERR 使用File :: Slurp; my @output = read_file($ out_filename);

  3. 打開管道並從中讀取。

    open(my $ output_fh,「./xxx.exp $ cmd |」)或死「無法運行程序:$!\ n」; while my $ line(){ #用$行做點事 } close($ output_fh);

  4. 使用標準IO模塊之一。例如。你可以繞過Expect並直接通過OUT和IN進行播放IPC::Open2

+0

我結束了使用IPC :: Open3。 –

+0

@AndyThompson - 順便說一句,我沒有把它添加到答案中,但要注意TLP不安全的代碼評論。將隨機字符串放入系統調用中應該非常小心。 – DVK