我想从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过滤器,我可以很好地捕获状态消息。
任何关于发生了什么的线索?
答案 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?是迄今为止我发现的缓冲效果的最佳解释。值得花时间阅读和理解。
不要忘记缓冲是有原因的,所以不要只是为了解决每个可能的问题而关闭它。