2017-12-05 17 views
2

これは可能かどうかわかりませんが、コマンドの出力をソケット上に送信しているので、コマンド実行中にクライアントコンピュータとサーバーコンピュータの両方に表示されます。バッククォートを使用しようとすると、コマンドが完了するまで出力が変数に保存されません。これは長い時間がかかるコマンドを実行すると悪いことです。リアルタイムバックテック出力処理

質問:別のプロセスを起動して変数を「監視」するという方法で、行単位で出力をスキャンする方法はありますか?

編集:これは私が、私は、出力がコマンドが完了する前に示すことを希望オープン

open DATA, "pause |" or die "Failed: $!"; 
while(defined(my $line = <DATA>)){ 
    chomp($line); 
    print "$line\n"; 
} 

と試みたものです。

+0

私はソケットがバックチックと関係しているのか分かりません。あなたは、プログラムのSTDOUTやソケットを読みたいと思っていますか? – ikegami

+0

私はstdoutを非同期に読み込み、改行がstdoutに追加されるとすぐに出力したいと考えています。ソケットの部分は重要ではありません。 – TheAschr

+0

1つ以上の入力**から**非同期的に読み取るには、0以上のクライアントにイベントを送信するには、*非ブロッキングIO *を使用し、すべてのIOを同時にアドレス指定するために 'select'コマンドを使用する必要があります... –

答えて

6

あなたは正しいアプローチをしています。

STDOUTに書き込む場合STDOUTは、端末(「ラインバッファリング」)であるとき、改行が検出されたとき、ほとんどのプログラムは、それらの出力をフラッシュ
my @cmd = ('perl', '-e', '$|=1; for (1..5) { print "$_\n"; sleep 1; }'); 

open(my $pipe, '-|', @cmd) 
    or die("Can't launch child: $!\n"); 

while (defined(my $line = <$pipe>)) { 
    chomp($line); 
    print "<$line>\n"; 
} 

。ほとんどのプログラムは、STDOUTが端末でない場合(「ブロックバッファリング」)、4KiBまたは8KiBの出力チャンクをブロックします。そのため、上記の例の子プログラムで$|=1;を使用しなければならなかったのです。

説明どおりに動作するプログラムは、パイプの代わりに擬似端末を使用するラインバッファリングを使用することになります。

my @cmd = ('unbuffer', 'perl', '-e', 'for (1..5) { print "$_\n"; sleep 1; }'); 

open(my $pipe, '-|', @cmd) 
    or die("Can't launch child: $!\n"); 

while (defined(my $line = <$pipe>)) { 
    chomp($line); 
    print "<$line>\n"; 
} 

IPC::Runは、擬似端末を作成するネイティブな方法を提供します。

use IPC::Run qw(run); 

my @cmd = ('perl', '-e', 'for (1..5) { print "$_\n"; sleep 1; }'); 

my $buf = ''; 
run(\@cmd, '>pty>', sub { 
    $buf .= $_[0]; 
    while ($buf =~ s/^(.*)\r\n//) { 
     print "<$1>\n"; 
    } 
}); 
+0

'unbuffer'です。私は以前にそれを知っていただけ...しかし、それはインストールする必要があります、そうですか?私のUbuntuは、それが 'expect'パッケージの一部だと言います。 – PerlDuck

+0

ファイルハンドルとして 'DATA'を使用するとうまくいくと思いますか? OPはそれを使用しますが、私は疑いの余地があります。 – PerlDuck

+1

@PerlDuckはい、 'unbuffer'をインストールする必要があります。そのため、IPC :: Runに組み込みのメソッドがあります(例を追加しました)。 ///はい、「データ」は再オープンできます。もちろん、 'DATA'は既に意味を持ち、グローバル(語彙ではない)変数なので、' DATA'を使うのは良い考えではありません。 – ikegami