Linux rsync: ファイルをローカルおよびSSH経由で同期する方法

rsync は、ファイルやディレクトリをローカルまたはリモートのシステムにコピーし、変更を転送するツールです。デフォルトの動作は、ソースから宛先への一方向コピーであり、宛先にのみ存在するファイルは --delete が指定されない限り削除されません。

始める前に

例はLinuxシェルで実行されます。まず、rsync --versionでインストールされているか確認してください。Ubuntuの場合、インストールされていない場合は、次のコマンドでインストールできます。リモート転送には、両方のシステムでrsyncが必要で、SSH(セキュアシェル)を使用する場合は、リモートアクセスおよび宛先パスでの書き込み権限も必要です。

sudo apt update
sudo apt install rsync

ソースとターゲットのパスを逆に入力すると、意図したデータを上書きまたは削除する可能性があります。重要なデータを扱う前に、必ず別のバックアップを確保してください。特に削除オプションを使用する場合は、まず--dry-runで予想される変更を確認してください。同期は、以前のポイントを復元するバックアップとは異なり、ソースのミスや破損もターゲットに反映されることがあります。

ローカルディレクトリのコピーとスラッシュの違い

以下はホームディレクトリの下に新しい練習用フォルダを作成し、1つのファイルを準備する例です。同名のフォルダが既に存在する場合は、別の名前を使用してください。

mkdir -p "$HOME/rsync-demo/source" "$HOME/rsync-demo/dest"
printf 'hello\n' > "$HOME/rsync-demo/source/hello.txt"
rsync -av "$HOME/rsync-demo/source/" "$HOME/rsync-demo/dest/"
ls -l "$HOME/rsync-demo/dest/"

前回のコマンドの結果にhello.txtが表示された場合、ソースディレクトリの内容がターゲットにコピーされています。同じrsyncコマンドを再度実行しても、通常は変更されていない一般ファイルは再転送されません。基本的な比較はファイルサイズと変更日時を使用するため、内容が同じであることを完全に確認するものではありません。

ソースの最後の / は、ディレクトリ自体ではなく、その中の内容がターゲットにコピーされることを意味します。ターゲットディレクトリがすでに存在していてスラッシュを省略した場合、ソースディレクトリ名がターゲットの下に作成されます。

rsync -av "$HOME/rsync-demo/source" "$HOME/rsync-demo/dest/"

このコマンドを実行すると dest/source/hello.txt が作成されます。以前に作成された dest/hello.txt はそのまま残ります。2つのパスの違いは、特に削除オプションを使用する場合に重要です。パスにスペースが含まれる場合は、例のように引用符で囲んでください。

よく使うオプションと事前チェック

  • -a: これはアーカイブモードです。再帰的なコピーを行い、時間、権限、所有者、グループ、シンボリックリンクを保持します。所有権の保持は、権限やターゲットファイルシステムのサポートによって制限される場合があります。ACLや拡張属性は-aには含まれません。
  • -v: 詳細な操作出力を表示します。
  • -nまたは--dry-run: 実際に変更を加えずに、予想される操作を表示します。
  • -z: 転送中に圧縮を使用します。効果はネットワーク条件やファイルタイプによって異なり、ローカルコピーでは常に必要なわけではありません。

例えば、実際にコピーを行う前に、次のように確認することができます。出力は予想される変更を示しますが、試行実行と実際の実行の間にファイルが変更されたりエラーが発生した場合、実際の結果は異なる場合があります。

rsync -avn "$HOME/rsync-demo/source/" "$HOME/rsync-demo/dest/"

同じサイズや更新日時のファイルが実際に異なる内容であるかどうかを確認する必要がある場合、--checksum 比較を検討することができますが、両方のファイルを読み込む必要があるためコストがかかる場合があります。オプションの詳細な意味については、rsync公式マニュアル を参照してください。

宛先にのみ存在するファイルの削除

--delete は、ソースに存在しない同期対象ディレクトリの項目を削除します。誤って間違った宛先やディレクトリレベルを指定すると、必要なファイルも削除される可能性があるため、まず対象パスとソースの末尾スラッシュを確認し、テスト実行の結果を確認してください。

以下の例は、上記で作成した dest/source/ のように、削除対象となる宛先にのみ存在する項目を一覧表示することができます。練習用フォルダーに残しておくファイルがない場合にのみ実行してください。

rsync -avn --delete "$HOME/rsync-demo/source/" "$HOME/rsync-demo/dest/"

出力の deleting エントリを確認し、削除範囲が正しく、復元用のバックアップが準備されている場合のみ、-n を外して実際に実行してください。

rsync -av --delete "$HOME/rsync-demo/source/" "$HOME/rsync-demo/dest/"

このコマンドは宛先のみを変更し、ソースからファイルを削除することはありません。宛先にのみ存在していたファイルは、通常のファイル復旧手順なしでは回復できない場合があります。運用データについては、別途バージョンバックアップと復元確認を準備してください。

ファイルまたはディレクトリの除外

転送対象からソースのcacheディレクトリを除外するには、次のように指定します。ソースの内容が転送ルートであるため、先頭のスラッシュはそのルートにあるcacheを指します。まずは、対象外となる項目が正しく除外されることを確認するために試行を実行してください。

rsync -avn --exclude='/cache/' "$HOME/rsync-demo/source/" "$HOME/rsync-demo/dest/"

結果が正しい場合は、-n を削除してコピーします。デフォルトの除外ルールは通常、--delete にある対象の除外項目を保護しますが、--delete-excluded を使用したりフィルタールールを変更したりすると動作が変わる場合があります。複雑なパターンは、実際のデータに適用する前に別のフォルダで確認してください。

SSH を介してリモートサーバーと同期する

SSH アクセスが準備できている環境では、次のコマンドによりローカルのソース内容をリモートサーバーのターゲットディレクトリに送信します。user、server.example.com、およびパスを実際の値に置き換え、リモートのターゲットディレクトリを事前に準備してください。初めて接続する場合は、信頼できる経路でサーバーのホストキーのフィンガープリントを確認してください。

rsync -avn -e ssh "$HOME/rsync-demo/source/" user@server.example.com:/home/user/backup/

期待される転送リストを確認した後、転送するために-nを削除します。逆に、リモートサーバーからローカルマシンに取得する場合は、リモートパスをソースの場所として設定します。

rsync -avn -e ssh user@server.example.com:/home/user/backup/ "$HOME/rsync-demo/dest/"

SSHポートがデフォルトと異なる場合、例えば-e 'ssh -p 2222'を使用します。リモートアクセスには、権限が制限されたアカウントおよびSSHキー認証の使用が推奨されます。コマンドにパスワードを直接入力しないでください。プロセス情報やシェル履歴に露出する可能性があるため、前の記事でのsshpass -pの例は使用されません。自動化タスクでは、キーの保護とアクセス範囲を一緒に管理します。