2009-03-23 20 views
2

rsyncプロセスによって生成されたすべての進行状況メッセージをPerlスクリプトから取得します。状況によっては、これは機能しません。ここでPerlでrsyncの進行状況メッセージを取得するにはどうすればよいですか?

は、私が使用して、典型的なrsyncコマンドラインです:

rsync -aL --verbose --progress --bwlimit=100 \ 
    --include-from=/tmp/78hJ2eDCs1 \ 
    --include '*/' --exclude '*' \ 
    /srcdir/* \ 
    hostname:/target/ 2>&1 

私はbashシェルの中にこれを実行すると、私はこのような何かわかります。私は、同じコマンドをしようとした場合

Building file list ... 
1600 files... 
1700 files... 
and so on 

をPerl内では、 "ビルドファイルリスト"出力はOKですが、ステータスは更新されません。ここで私は

my $pid = open(OUTPUT, "$cmd |") or die "Couldn't fork: $!\n"; 

my $ch; 
while(read(OUTPUT, $ch, 1)==1) 
{ 
    print $ch; 
} 
close(OUTPUT); 

キャプチャをテストする方法です私の推測では、どちらかのrsyncは、出力ハンドルを感知することで、一般的なコンソールではないか、私はキャプチャしていないよ、いくつかの珍しい形で出力されています。 しかし、それをさらに奇妙にするのは、--includeおよび--excludeフィルタを省略すると、ステータスメッセージをうまくキャプチャできることです。

何が起こっているかについての手がかりはありますか?

+0

2つの回答が既に提供されていると、私はrsyncが出力をバッファするために何かしていると推測しています。最後にすべての出力を得ますか? –

答えて

3

ソリューションは簡単だったが判明 - 私はちょうど$| = 1;

と私のスクリプトでIOをバッファー解除しなければならなかった私は、まだ私はいくつかのrsyncのオプションではなく、他に問題があることを観察する方法で困惑しています。私にアイデアを与えてくれてありがとうPaul Tomblinとdsm。

+0

面白い、私は$ | - > autoflushは同等でしたので、私はそれを提案しました。 –

+0

私はautoflushがOUTPUTハンドルに作用したと思いますが、$ | STDOUTスクリプトで動作していましたか?つまり、何とか出力をフラッシュしていないだけですか? –

4

パイプからの出力をバッファしますか?もしそうなら、OUTPUTハンドルを開いた後、OUTPUT-> autoflush(1)でバッファリングを止めれば、それを働かせることができるかもしれません。

+0

私はそれを無駄にしようとしました。 - 奇妙なことは、--include/excludeオプションを使用しないとすべての出力をキャプチャできることです。 –

4

PTYを模倣するExpect.pmを使用すると、探している出力が得られる場合があります。

これに失敗すると、--statsまたは--progressオプションを試すことができます。

+0

私は単にExpectで出力を繰り返し食べることができますが、擬似TTYを模倣するというアイデアは実りあると証明されるかもしれません。 –

+0

いいえ、私はIO :: Pty :: Easyを使ってみました。全く同じ動作を見ました。 –

0

IPC :: Runを使用し、stdout/stderrのデータのコールバックを使用することもできます。

0

Suffering from Buffering?これまでに発見したバッファリングの効果についての最も良い説明です。読んで理解する時間の価値があります。

バッファリングには理由があることを忘れないでください