强制 rsync 逐行输出消息

强制 rsync 逐行输出消息

(我不确定这个问题是否应该在 StackOverflow 上或这里进行。但实际问题在于rsync,所以总的来说,我认为这是一个 Linux 问题。如果管理员不同意,请务必迁移它。)

我正在尝试rsync从另一个程序运行(在本例中是用 Ruby 编写的,尽管它可以很容易地用任何其他语言编写)并逐行捕获其输出。

(在 Ruby 中,这是通过Open3#popen3IO.select来电。在 Python 中,人们会使用asyncio.create_subprocess_shell。)

然而 - 与我遇到过的几乎所有其他终端命令不同 -rsync绝对拒绝当以这种方式运行时(即,当不从具有真实 tty 的终端运行时),逐行写入其输出。相反,它“缓冲”其输出,并且只在最后(或者大概是当缓冲区已满时)发送它。也许它不是flush管道?无论出于何种原因,这都是一个严重的问题。这意味着我的脚本无法向用户显示进度消息(例如百分比);相反,我们会看到长达一个小时的完全无线电静默(或者无论手术需要多长时间)。

我读到该--outbuf=L参数正是针对这种情况而存在的。然而,它不起作用。至少在我的 rsync 版本上是这样,它是 3.2.7。

互联网上有人建议了该--msgs2stderr参数,但这也没有帮助。

我用 Python 编写了一个简单的测试,以确保这不是 Ruby 问题,使用了修改后的版本这个示例代码。结果是相同的,因此问题可能出在 rsync 上。

所以,我的问题很简单:我该如何力量rsync 逐行输出进度消息,而不是“保存它们”并在最后将它们打印在一个大转储中?

额外说明

rsync在本地运行。这是我正在使用的确切命令的示例:

rsync --verbose --msgs2stderr --progress --relative --links
--hard-links --perms --owner --group --times --sparse
--one-file-system --human-readable --delete --delete-excluded
--recursive --prune-empty-dirs --outbuf=L --from0
'/mnt/data' '/mnt/backup'
--exclude-from=/tmp/rsbackupexclusionlist20230816-2064241-6nghn7

我可以确认我的 Ruby 代码可以正确处理其他程序,例如apt-getgit或。 (我不知道也没有测试过。)makedebootstrapyes

同时我的研究表明,rsync当检测到没有附加 PTY 时,不会正确刷新其 STDOUT 或 STDERR 输出。

从那时起,我已经取得了一些成功,rsync通过 Ruby 记录不充分的PTY.spawn指令执行,该指令创建一个 PTY 并将命令的输出通道附加到它。但这并不理想。一方面,它将 STDOUT 和 STDERR 合并到一个流中。

如果绝大多数其他软件“都能正常运行”,为什么rsync拒绝运行良好呢?有没有办法让它工作,而不使用PTY.spawn

为什么什么--outbuf=L也不做?

答案1

我无法复制这个。

我使用 rsync 3.2.7 并从抓取 stderr 的 python 脚本运行它。它立即显示输出,而不是等到结束。

我没有使用完全相同的 rsync 选项(我没有处理异常列表),但我认为所有相关的选项都已使用。 (我认为无论是否包含都没有区别--outbuf=L

看看你是否可以用这个程序复制它。

import subprocess
import sys


s = subprocess.Popen(["rsync", "-av", "--msgs2stderr", "--outbuf=L", "--progress", "lots_o_files/", "lots2/", ], stdout=subprocess.PIPE, stderr=subprocess.PIPE)


while (True):
    nextline = s.stderr.readline()
    if nextline == b'' and s.poll() is not None:
        break
    sys.stdout.write(nextline.decode())
    sys.stdout.flush()

输出:

sending incremental file list
8m28V3/qG81EA/TViGDb/
8m28V3/qG81EA/TViGDb/XOarqQ.txt
            755 100%    0.00kB/s    0:00:00 (xfr#1, ir-chk=1008/15161)
8m28V3/qG81EA/TViGDb/Zhe0F6.txt
            742 100%  724.61kB/s    0:00:00 (xfr#2, ir-chk=1007/15161)
8m28V3/qG81EA/TViGDb/a1B3ha.txt
            847 100%  827.15kB/s    0:00:00 (xfr#3, ir-chk=1006/15161)
...

如果立即打印输出,则 rsync 必须立即生成输出(没有 TTY)。如果这等到最后,那么我们的系统就会有一些不同(或者我没有复制的 rsync 选项是相关的)。

相关内容