【rsync】差分同期・バックアップの使い方|末尾スラッシュの罠・delete同期・-n確認

【rsync】差分同期・バックアップの使い方|末尾スラッシュの罠・delete同期・-n確認 SSH

rsyncは、ファイルやディレクトリを効率よく同期・バックアップするためのコマンドです。scpが「毎回まるごとコピー」なのに対し、rsync変更があった部分だけを転送する差分同期ができるため、2回目以降が圧倒的に速く、巨大なディレクトリや定期バックアップに向いています。SSH経由でリモートサーバーとも同期でき、サイトのデプロイやバックアップの定番ツールです。

ただしrsyncには、初心者が必ずと言っていいほどハマる罠があります。それがコピー元の末尾スラッシュ(srcsrc/)で結果が変わることです。そして削除を伴う--deleteは強力なぶん危険なので、-n(お試し実行)で事前確認する習慣が欠かせません。この記事では、実機のLinux(WSLのDebian)で同期を実行しながら、rsyncの使い方と罠を整理します。

先に結論

  • 基本はrsync -av 元 先-aは権限・日時を保持、-vは経過表示です。
  • 変更分だけを転送する差分同期なので、2回目以降が高速です。
  • 末尾スラッシュに注意src/は「中身」、srcは「フォルダごと」を意味します。
  • 削除を伴う操作の前は-n(dry-run)で必ず確認します。
  • --deleteで送信元に無いファイルを受信側からも消せます(危険なので確認必須)。
  • SSH経由は-e "ssh -p ポート"、除外は--excludeを使います。

単発の転送で十分ならscpコマンド、接続設定の集約は~/.ssh/config、鍵認証の準備はssh-keygenもあわせて参考になります。

スポンサーリンク

基本と差分同期

基本形はrsync -av 元 先です。-a(アーカイブ)はディレクトリを再帰的に、権限やタイムスタンプを保ったままコピーする定番オプション、-vは処理内容の表示です。rsyncの真価は2回目以降に出ます。

基本と差分同期
# 基本形(-a: 権限・日時保持で再帰, -v: 経過表示)
rsync -av src/ backup/

# 1ファイルだけ変更して、もう一度同じコマンドを実行すると…
echo "更新" >> src/a.txt
rsync -av src/ backup/
# → 転送されるのは変更した a.txt だけ!(他は転送されない)
2回目は「変わったファイルだけ」転送(実証)

実機で確認したところ、初回に全ファイルを同期したあと、1つのファイル(a.txt)だけを変更して再度rsyncを実行すると、転送されたのはa.txtのみで、変更していないファイルは転送されませんでした。rsyncファイルのサイズと更新日時を比較し、変わったものだけを送るためです(さらに大きなファイルでは、ファイル内の変更された部分だけを送る仕組みも持っています)。この差分同期のおかげで、毎日のバックアップでも実際に転送されるのは「その日変わった分」だけになり、scpのように毎回全部コピーするより桁違いに高速です。-aを付ければ、実機でも確認したとおりタイムスタンプもそのまま保持されるので、バックアップの世代管理にも向いています。

【最重要】末尾スラッシュの罠

rsync最大の落とし穴がコピー元の末尾スラッシュです。src/(スラッシュあり)は「srcの中身」、src(スラッシュなし)は「srcフォルダそのもの」を意味し、結果がまるごと変わります。

src と src/ の違い
# スラッシュあり: src の「中身」が backup 直下に入る
rsync -a src/ backup/
# backup/a.txt, backup/b.txt, backup/sub/ ...

# スラッシュなし: src「フォルダごと」backup の下に入る
rsync -a src backup/
# backup/src/a.txt, backup/src/b.txt ...
#   → backup の中に src というフォルダができる
src/は「中身」・srcは「フォルダごと」(実証)

実機で両方を試したところ、rsync -a src/ dst/(スラッシュあり)では、dstの直下にa.txtb.txtsubというsrcの中身が展開されました。一方rsync -a src dst/(スラッシュなし)では、dstの中にsrcというフォルダthat丸ごと作られ、その下にファイルが入りました。この違いを知らないと、「backup/に同期したはずがbackup/src/という二重フォルダになっていた」「同期先の階層がずれてリンク切れした」といった事故が起きます。コピー元の末尾スラッシュは『中身だけ送る=/あり』と覚えるのが確実です(コピー先のスラッシュは結果に影響しません)。迷ったら、次に紹介する-nで結果を先に確認してください。

-n(dry-run)で事前確認

rsyncは削除や上書きを伴うため、本番の前に-n(または--dry-run)で「何が起きるか」を確認するのが鉄則です。-nを付けると、実際には何も変更せず、転送・削除される予定のファイル一覧だけを表示します。

-n で安全確認
# -n を付けると、実際には転送せず「予定」だけ表示
rsync -avn src/ backup/

# 表示を確認して問題なければ -n を外して本実行
rsync -av src/ backup/

# --delete を使うときは特に、必ず -n で先に確認する
rsync -avn --delete src/ backup/

実機でも、新しいファイル(d_new.txt)を追加してrsync -avnを実行すると、転送予定としてd_new.txtが表示されるものの、実際には同期先に作られていない(=転送されていない)ことを確認しました。-nは「予行演習」で、コマンドが意図どおりかを安全に確かめられます。とくに次の--deleteのように削除を伴う操作では、-nでの確認を絶対に省略しないでください。表示された一覧に、消えては困るファイルが含まれていないかをチェックしてから本実行します。

--delete(完全ミラー)と注意

--deleteを付けると、送信元に存在しないファイルを、受信側からも削除します。送信元と受信側を完全に一致(ミラー)させたいときに使いますが、消したくないファイルまで消える危険があります。

delete で完全ミラー
# 送信元に無いファイルを受信側から削除して完全一致させる
rsync -av --delete src/ backup/

# 【重要】必ず先に -n で確認
rsync -avn --delete src/ backup/
# deleting old.txt  ← このように削除予定が表示される
--deleteは「受信側の余分なファイル」を消す(実証)

実機で確認したところ、同期先に送信元には無いファイル(orphan.txt)を置いた状態でrsync -a --delete src/ dst/を実行すると、orphan.txtが同期先から削除され、送信元と完全に一致しました。これは「送信元を正」としてミラーを作れる強力な機能ですが、裏を返せば受信側にしか無い大切なファイルも問答無用で消えるということです。とくに末尾スラッシュの罠と組み合わさると悲劇的で、コピー元の指定を間違えたまま--deleteすると、同期先が意図せず空になることもあります。--deleteを使うときは、必ず-nで削除予定(deleting ...の行)を確認し、消える一覧に問題がないと納得してから実行してください。

SSH経由でリモート同期・除外

rsyncSSH経由でリモートサーバーと同期できます。リモート側はscpと同じユーザー@ホスト:パスで指定し、ポートが22以外なら-e "ssh -p ポート"を付けます。不要なファイルは--excludeで除外します。

リモート同期と除外
# ローカル → リモートサーバーへ同期(SSH経由)
rsync -av -e "ssh -p 10022" ./public_html/ user@example.com:/home/user/public_html/

# リモート → ローカルへバックアップ取得
rsync -av -e "ssh -p 10022" user@example.com:/home/user/public_html/ ./backup/

# 除外しながら同期(ログや node_modules を送らない)
rsync -av --exclude '*.log' --exclude 'node_modules' src/ backup/

# 圧縮しながら転送(低速回線で有効)
rsync -avz -e "ssh -p 10022" src/ user@example.com:/home/user/

--excludeは実機でも、*.lognode_modulesを指定するとそれらを除いて同期できることを確認しました(keep.txtだけが同期され、ログとフォルダは除外)。デプロイで開発用ファイルを送りたくないときに重宝します。SSH経由の書き方はscpと同じ考え方で、-e "ssh -p ポート"でポートや鍵(-e "ssh -p 10022 -i ~/.ssh/id_ed25519")を指定できます。接続情報を~/.ssh/configに登録しておけば、rsync -av src/ myserver:/path/のように別名だけで同期でき、さらに手軽になります。低速回線では-z(圧縮)が効きます。

主なオプション一覧

rsyncでよく使うオプションをまとめます。

オプション 働き
-a アーカイブ(再帰・権限・日時を保持)
-v 処理内容を表示
-n / --dry-run お試し実行(実際には変更しない)
-z 転送を圧縮(低速回線で有効)
--delete 送信元に無いファイルを受信側から削除
--exclude 'パターン' 指定にマッチするものを除外
-e "ssh -p 番号" SSH経由(ポート・鍵の指定)

よくある失敗

末尾スラッシュで階層がずれる

src/は中身、srcはフォルダごとです。二重フォルダを避けるには-nで先に確認します。

--deleteで必要なファイルを消す

受信側だけにあるファイルも消えます。必ず-nで削除予定を確認してから実行します。

-nを付けずにいきなり本実行する

削除・上書きを伴う操作は取り消せません。-nでの予行演習を習慣にします。

リモートのポート指定を忘れる

22以外は-e "ssh -p 番号"が必要です。~/.ssh/configに書いておくと省けます。

不要なファイルまで同期する

--excludeでログやnode_modulesなどを除外します。

よくある質問

Qrsyncとscpはどう使い分けますか?
A単発のファイル転送や少量のやり取りはscpが手軽です。繰り返しの同期・巨大なディレクトリ・定期バックアップには、変更分だけを転送する差分同期ができるrsyncが向いています。実機でも、2回目の同期では変更したファイルだけが転送されることを確認しています。
Qsrc と src/ で結果が変わるのはなぜですか?
Aコピー元の末尾スラッシュは「中身か、フォルダごとか」を表すためです。src/(あり)はsrcの中身を同期先の直下に、src(なし)はsrcフォルダごと同期先の下に置きます。実機でも、スラッシュありは中身が展開され、なしは同期先にsrcフォルダができることを確認しています。迷ったら-nで結果を先に確認してください。
Q--deleteは危険と聞きました。安全に使うには?
A--deleteは送信元に無いファイルを受信側から削除するため、消したくないファイルまで消える恐れがあります。必ずrsync -avn --delete ...のように-nを付けて実行し、deleting ...と表示される削除予定を確認してから、問題なければ-nを外してください。
Qリモートサーバーにrsyncで同期するには?
ASSH経由でrsync -av -e "ssh -p 10022" ./src/ user@example.com:/home/user/dst/のように書きます。リモート側はscpと同じユーザー@ホスト:パス形式で、ポートが22以外なら-e "ssh -p 番号"を付けます。~/.ssh/configに登録すれば別名だけで同期できます。
Q特定のファイルを同期から除外できますか?
A--exclude 'パターン'で除外できます。--exclude '*.log' --exclude 'node_modules'のように複数指定も可能です。実機でも、ログファイルやnode_modulesを除いて同期できることを確認しています。デプロイで開発用ファイルを送りたくないときに便利です。

まとめ

  • 基本はrsync -av 元 先2回目以降は変更分だけの差分同期で高速です。
  • 末尾スラッシュに注意src/は中身、srcはフォルダごと。
  • 削除・上書きの前は-n(dry-run)で必ず確認します。
  • --deleteは完全ミラー(危険)、--excludeで除外、-zで圧縮。
  • SSH経由は-e "ssh -p 番号"~/.ssh/config登録で別名同期も可能です。

rsyncは、バックアップとデプロイを効率化する強力なツールです。「末尾スラッシュは中身か丸ごとか」「削除の前は必ず-n」の2点さえ体に入れれば、事故なく高速な同期ができます。鍵認証~/.ssh/configと組み合わせて、快適なバックアップ・デプロイ環境を整えましょう。