2016-10-09 3 views
1

私はthis questionにIPC ::のopen3について尋ねました。しかし、私はまだ問題があります。多くの問題::の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/)のように聞こえ始めています。あなたは最終的にやろうとしていることを説明できますか?シェルコマンドを実行してSTDERRとSTDOUTをキャプチャし、STDOUTをユーザーに表示するようにしたいと思っています。また、STDINをスクリプトから取り出してシェルコマンドにも送りたいのですか? – dasgar

+0

あなただけのシェルコマンドからのSTDERRとSTDOUTをキャプチャしたい場合は、[キャプチャ::タイニー](https://metacpan.org/pod/Capture::Tiny)からのキャプチャ機能をチェックアウトすることができます。 STDERR、STDOUT、および終了コードをキャプチャできます。また、STDOUTとSTDOUTをキャプチャしながらSTDOUTを表示したい場合は、Capture :: Tinyからのtee関数の1つがうまくいくでしょう。 – 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エラーの場合はfalseを返しません。それは例外をスローします。

コマンドとして単一のスカラーを渡すと、それは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); 
関連する問題