Perl を使用して、外部プログラム (シェル コマンド) の出力を 1 行ずつ解析したいと考えています。コマンドは継続的に実行されるため、スレッドに配置し、共有変数を使用してメイン ルーチンと通信します。
今まで私のコードは次のように見えます
#!/usr/bin/perl
use warnings;
use strict;
use threads;
use threads::shared;
my $var :shared; $var="";
threads->create(
sub {
# command writes to stdout each ~100ms
my $cmd = "<long running command> |";
open(README, $cmd) or die "Can't run program: $!\n";
while(<README>) {
my $line = $_;
# extract some information from line
$var = <some value>;
print "Debug\n";
}
close(README);
}
);
while(1) {
# evaluate variable each ~second
print "$var\n";
sleep 1;
}
一部のコマンドでは、これは完全に正常に機能し、行は入力されたとおりに処理されます。出力は次のようになります。
...
Debug
Debug
...
<value 1>
...
Debug
Debug
...
<value 2>
...
ただし、他のコマンドの場合、これは奇妙な動作をし、行はブロックごとに処理されます。その$var
ため、更新されDebug
ず、しばらく印刷されません。次に、突然、出力は次のようになります (に似ています):
...
<value 1>
<value 1>
<value 1>
...
Debug
Debug
Debug
...
<value 20>
$var
最後/現在の値に設定されます。その後、これが繰り返されます。解析は常に遅延され、ブロック単位で行われますが、途中$var
で更新されることはありません。
まず第一に:パイプを使用する以外に、外部プログラムの出力を(行ごとに)解析するためのより良い/適切な方法はありますか?
そうでない場合、どうすればこの動作を回避できますか?
autoflush(1);
またはを使用$|=1;
すると解決策になる可能性がありますが、「現在選択されている出力チャネル」に対してのみです。私の文脈でそれをどのように使用しますか?
前もって感謝します。