如何在Perl中捕获rsync进度消息?

时间:2009-03-23 12:07:04

标签: perl rsync

我想从Perl脚本捕获rsync进程发出的所有进度消息。在某些情况下,这是行不通的。

这是我使用的典型rsync命令行:

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

如果我在bash shell中运行它,我会看到类似这样的内容:

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

如果我在Perl中尝试相同的命令,我会得到“构建文件列表”输出,但不是状态更新。以下是我测试捕获的方法

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过滤器,我可以很好地捕获状态消息。

任何关于发生了什么的线索?

5 个答案:

答案 0 :(得分:4)

perl是否缓冲了管道的输出?如果是这样,如果在打开OUTPUT句柄后,你可以使用OUTPUT-> autoflush(1)关闭缓冲;

答案 1 :(得分:4)

您可以使用模仿PTY的Expect.pm,它可以为您提供所需的输出。

如果失败,您可以尝试--stats--progress选项。

答案 2 :(得分:3)

原来解决方案很简单 - 我只需要在我的脚本中使用$| = 1;取消缓冲IO

我仍然对我如何观察某些rsync选项的问题感到困惑,而不是其他选项。感谢Paul Tomblin和dsm给我的想法。

答案 3 :(得分:0)

您可能还想使用IPC :: Run及其对stdout / stderr上的数据进行回调。

答案 4 :(得分:0)

Suffering from Buffering?是迄今为止我发现的缓冲效果的最佳解释。值得花时间阅读和理解。

不要忘记缓冲是有原因的,所以不要只是为了解决每个可能的问题而关闭它。