2

我想从 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 中尝试相同的命令,我会得到“构建文件列表”输出 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 过滤器,我可以很好地捕获状态消息。

有人知道发生了什么吗?

4

5 回答 5

4

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

于 2009-03-23T12:13:34.667 回答
4

您可以使用模仿 PTY 的Expect.pm,它可能会为您提供您正在寻找的输出。

如果做不到这一点,您可以尝试--statsor--progress选项。

于 2009-03-23T12:15:17.097 回答
3

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

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

于 2009-03-23T14:02:05.437 回答
0

您可能还想使用 IPC::Run 它是标准输出/标准错误上数据的回调。

于 2009-03-23T15:21:40.750 回答
0

受缓冲之苦?是迄今为止我发现的关于缓冲效果的最佳解释。非常值得花时间阅读和理解。

不要忘记缓冲是有原因的,所以不要盲目地为每个可能的问题关闭它。

于 2009-07-31T12:17:38.993 回答