rsyncがメッセージを1行ずつ出力するように強制する

rsyncがメッセージを1行ずつ出力するように強制する

(この質問がStackOverflowにあるのか、ここにあるのかわかりませんが、実際の質問は一般rsync的にLinuxの問題だと思います。管理者が同意しない場合は必ず移行してください。)

私はrsync別のプログラム(この場合はRubyで書かれていますが、他の言語でも簡単に書くことができます)で実行して出力を1行ずつキャプチャしようとしています。

(Rubyでは、以下を介して行われます。Open3#popen3そしてIO.select着信電話。 Pythonでは、人々がasyncio.create_subprocess_shell。 )

しかし - 私が出会った他のほとんどすべての端末コマンドとは異なり -rsync絶対に拒否するこのように実行すると(つまり、実際のttyを持つ端末で実行されていない場合)、出力は1行ずつ書き込まれます。代わりに出力を「バッファリング」し、最後にのみ出力します(またはおそらくバッファがいっぱいになったとき)。おそらくflushパイプではないですか?理由が何であれ、これは深刻な問題です。これは、私のスクリプトがユーザーに進行状況メッセージ(パーセントなど)を表示できないことを意味します。代わりに、最大1時間(または手術にかかる時間)、完全なワイヤレスサイレントを見ることができます。

--outbuf=Lまさにこの状況に対してこのパラメータが存在することを読んでいます。しかしそれは動作しません。少なくとも私のrsyncバージョン3.2.7ではそうです。

インターネットの誰かがこのパラメータを--msgs2stderr提案しましたが、それも役に立ちませんでした。

修正されたバージョンを使用して、これがRubyの問題ではないことを確認するためにPythonで簡単なテストを作成しました。このサンプルコード。結果は同じで、rsyncに問題がある可能性があります。

だから私の質問は簡単です。どうすればいいですか?rsyncは「保存」して最後に1つの大きなダンプとして印刷するのではなく、1行ずつ進行メッセージを出力しますか?

追加のガイドライン

ローカルで実行しています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

apt-get私のRubyコードが、またはなどの他のプログラムで正しく機能していることを確認できますgit。 (私も知らず、テストしたこともありません。)makedebootstrapyes

また、私の研究では、rsync接続されたPTYが検出されないと、STDOUTまたはSTDERR出力が正しくフラッシュされません。

それ以来、私はPTYを生成し、コマンドの出力チャネルをここに接続するrsyncRubyの正しく文書化されていないディレクティブを介して実行に成功しました。PTY.spawnしかし、それは理想的ではありません。一方では、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オプションが関連しています)。

関連情報