ローカルファイルが更新されたかどうかをrsyncで報告する

ローカルファイルが更新されたかどうかをrsyncで報告する

リモート ホストからローカル ホストにプルするために rsync を実行しています。

rsync -a --update user@remotehost:/files/ ~/files/

私は Java からそのコマンドを実行し、終了コードを使用してそれが成功したかどうかを判断しています。

ローカル ファイルが変更されたかどうかをそのコマンドで報告させることは可能ですか? 終了コードで報告するのが理想的です。

答え1

rsync終了コードでそれを通知することはできません。終了コードには、定義済みの意味が文書化されています。

--info=NAMEJava からこれを行う最善の方法は、更新されたディレクトリとファイル名のみを指定するオプションを追加することだと思います。

rsync -a --info=NAME --update user@remotehost/files/ ~/files/

これにより、更新されたファイルとディレクトリの名前が 1 行に 1 つずつ標準出力 (fd = 0) に出力されます。

次に、出力を収集しrsync、文字列内の改行の数をカウントします。

出力を収集する良い方法はjavaこの回答に記載されていると思いますが、試したことはありません。https://stackoverflow.com/a/9048519/5484716

するない標準出力を標準エラー ストリームとマージしたり、その他の方法でマージredirectErrorStreamしたりしないでください。これを行うと、エラー メッセージは更新されたファイルとしてカウントされ、必要なファイルではなくなります。

答え2

rsync にコピーされたファイル名を印刷させるという @DavidKing のアイデアに基づき、stdin が空の場合に grep は非ゼロの終了ステータスで終了するという @yashma の情報で拡張すると、満足のいくほど短くて謎めいたワンライナーを作成できます。

# prints file list, exits nonzero when that list is empty
rsync -a --info=NAME --update user@remotehost:/files/ ~/files/ | grep .

答え3

--infoフラグをオンにすると、rsync転送されたファイルのパスが出力されます。 の終了コードは成功rsync/失敗を示すため、次のようにコマンドをスクリプトで囲まないと使用できません。

#!/bin/bash

files=$(rsync -a --info=NAME --update user@remotehost/files/ ~/files/)

if [ $files = "" ]; then
  # files weren't transferred
  exit 0
else
  # files were transferred
  exit 1
fi

そして、rsyncコマンドを直接呼び出すのではなく、Java からそのスクリプトを呼び出します。 rsync送信の最初と最後に他のテキスト行が出力される可能性が高いため、出力ifの追加行を考慮してステートメントを調整する必要があるかもしれませんが、基本的な考え方は機能します。

答え4

戻りコードによって情報を取得するには、rsyncJava からシェル スクリプトを呼び出して実行するシェル スクリプトを作成します。以下に概説するように、これにはいくつかの大きな問題があります。シェル スクリプトは次のようになります。

#!/bin/sh
if OUTPUT=$(rsync -a --info=NAME --update user@remotehost/files/ ~/files/)
then
    if [ "$OUTPUT" != "" ]                   # got output?
    then
        exit 0  # yes, success, "some" files were updated
    fi
fi
exit 1  # either rsync failed or no files were updated

これの主な問題は、同期プロセス自体が正常に完了したかどうかがわからないことです。ファイルが更新されたかどうかしかわかりません。そのため、Javaで出力を収集し、行数を数えることをお勧めします。そして戻りコードを確認するジャワで

関連情報