2016-10-09 105 views
1

我詢問了有關IPC :: Open3的this question。但是,我仍然有問題。IPC的更多麻煩:: Open3

此代碼掛起,而不是等到在標準輸入顯示EOF。它也沒有寫任何東西給stderr。

這不是重複的,因爲該問題詢問捕獲輸出,而此問題詢問輸入。

#!/usr/bin/env perl 

use strict; 
use warnings; 
use utf8; 
use v5.10; 

use IPC::Open3; 

use Symbol 'gensym'; 

my $output; 
# pipe my $input, $output or die $!; 
my $pid = open3(\*STDIN, $output, \*STDERR, 'sh', 
    '-c', 'echo 1 >&2; cat /usr/include/unistd.h -') or die $!; 


while (<$output>) { 
    say $output; 
} 
waitpid $pid, 0; 
+0

這聽起來像是[X Y問題](http://xyproblem.info/)。你能解釋一下你最終想做什麼嗎?看起來你想要做的一部分是執行一個shell命令並捕獲它的STDERR和STDOUT,並顯示STDOUT以供用戶看到。你是否也想從腳本中將STDIN發送到shell命令中? – dasgar

+0

如果您只想從shell命令中捕獲STDERR和STDOUT,可以從[Capture :: Tiny](https://metacpan.org/pod/Capture::Tiny)中查看捕獲函數。它可以讓你捕獲STDERR,STDOUT和退出代碼。如果您還想在顯示STDOUT的同時捕獲STDERR和STDOUT,那麼Capture :: Tiny的其中一個tee功能可能適合您。 – dasgar

+0

@ikegami我編輯了這個問題來解釋爲什麼這不是重複的。 – Demi

回答

1

你的程序具有以下問題:

  • \*STDIN(打開STDIN作爲綁在孩子的STDIN管道)應<&STDIN(使用父母的STDIN作爲孩子的STDIN)。
  • \*STDERR(打開STDERR作爲綁在孩子的STDERR管道)應>&STDERR(使用父母的STDERR作爲孩子的STDERR)。
  • say $output;應該是say $_;或只是say;
  • 您使用say,但您打印的值已換行符終止。首先使用chomp,或者切換到使用print
  • open3不是系統調用,所以它不設置$!
  • open3錯誤時不返回錯誤;它會拋出一個異常。

請注意,如果您傳遞一個標量作爲命令,它將傳遞到sh -c

#!/usr/bin/env perl 

use strict; 
use warnings; 
use v5.10; 

use IPC::Open3 qw(open3); 

my $pid = open3('<&STDIN', my $output, '>&STDERR', 
    'echo 1 >&2; cat /usr/include/unistd.h -'); 

while (<$output>) { 
    chomp; 
    say "<$_>"; 
} 

waitpid($pid, 0);