「--deleteを使ったら余計なファイルまで消えてしまいそうで怖い」
rsyncはLinuxでファイルの同期やバックアップを行う定番コマンドです。cpやscpと違い、差分だけを転送するため高速で、リモートサーバーとの同期にも対応しています。
この記事では、rsyncの基本操作から--dry-runによる事前確認、除外パターン、crontabとの連携まで、実務で必要な使い方を網羅します。
なぜrsyncなのか?(scpやcpとの違い)
ファイルのコピーや転送には、cp・scp・rsyncなど複数のコマンドがあります。rsyncが選ばれる理由は「差分転送」と「同期」の2点です。・cp:ローカルでのファイルコピー専用。毎回すべてのファイルをコピーする
・scp:SSH経由のリモートコピー。毎回すべてのファイルを転送する
・rsync:変更があったファイルだけを転送する。ローカルもリモートも対応
例えば、10GBのディレクトリで100MBだけ更新があった場合、scpは10GB全体を転送しますが、rsyncは100MBだけ転送します。日々のバックアップやデプロイのように繰り返し実行する作業では、rsyncが圧倒的に効率的です。
さらに、rsyncには--deleteオプションで「同期元に存在しないファイルを同期先から削除する」機能もあります。これにより、2つのディレクトリを完全に同じ状態に保てます。
rsyncの基本的な使い方
1. ローカルでのファイルコピー・同期
rsyncはリモート転送だけでなく、ローカルのディレクトリ同期にも使えます。# /home/user/data/ の内容を /backup/data/ に同期 rsync -av /home/user/data/ /backup/data/ # 単一ファイルのコピー rsync -av /home/user/report.txt /backup/
2. リモートサーバーとの同期(SSH経由)
rsyncはデフォルトでSSHを使ってリモートサーバーと通信します。# ローカル → リモートへ転送(プッシュ) rsync -av /home/user/data/ user@192.168.1.100:/backup/data/ # リモート → ローカルへ取得(プル) rsync -av user@192.168.1.100:/var/log/ /backup/logs/ # SSHポートが22以外の場合(例:2222番) rsync -av -e "ssh -p 2222" /home/user/data/ user@192.168.1.100:/backup/data/
3. --dry-runで安全に事前確認する
rsyncで最も重要なオプションの一つが--dry-run(-n)です。実際にはファイルを転送せず、「何が転送されるか」だけを表示します。# 実行前の確認(ファイルは一切転送されない) rsync -avn /home/user/data/ /backup/data/ # --deleteと組み合わせて、削除されるファイルも確認 rsync -avn --delete /home/user/data/ /backup/data/
実務で使うrsyncオプション
-aオプション(アーカイブモード)の中身
-aは複数のオプションをまとめたショートカットです。中身は以下の通りです。・-r:ディレクトリを再帰的にコピーする
・-l:シンボリックリンクをリンクのままコピーする
・-p:パーミッション(権限)を保持する
・-t:タイムスタンプを保持する
・-g:グループを保持する
・-o:オーナー(所有者)を保持する
・-D:デバイスファイルと特殊ファイルを保持する
つまり「-a = -rlptgoD」です。バックアップ目的では-aを付けるのが基本です。
--excludeで除外パターンを指定する
特定のファイルやディレクトリを同期対象から除外できます。# .logファイルを除外 rsync -av --exclude="*.log" /home/user/data/ /backup/data/ # 複数パターンを除外 rsync -av --exclude="*.log" --exclude="*.tmp" --exclude=".cache/" /home/user/data/ /backup/data/ # 除外パターンをファイルで指定 rsync -av --exclude-from="/home/user/exclude-list.txt" /home/user/data/ /backup/data/
# exclude-list.txt の例 *.log *.tmp .cache/ node_modules/
--deleteで同期元にないファイルを削除する
--deleteは、同期先にあって同期元にないファイルを削除するオプションです。# 同期先を同期元と完全に同じ状態にする rsync -av --delete /home/user/data/ /backup/data/
--progressと--statsで転送状況を確認する
# ファイルごとの転送進捗を表示 rsync -av --progress /home/user/data/ /backup/data/ # 転送完了後に統計情報を表示 rsync -av --stats /home/user/data/ /backup/data/
応用・実務Tips
定期バックアップをcrontabで自動化する
rsyncの真価はcrontabと組み合わせた定期バックアップで発揮されます。# crontab -e で以下を追加 # 毎日午前3時にバックアップを実行 0 3 * * * rsync -a --delete /home/user/data/ /backup/data/ >> /var/log/rsync-backup.log 2>&1 # 毎日午前3時にリモートサーバーへバックアップ 0 3 * * * rsync -a -e ssh /home/user/data/ user@backup-server:/backup/data/ >> /var/log/rsync-backup.log 2>&1
・SSH鍵認証を設定する:パスワード入力が求められると自動実行が止まる
・フルパスでコマンドを記述する:cron環境ではPATHが限定されるため、/usr/bin/rsyncのように絶対パスで記述すると確実
・ログを残す:>> でログファイルに追記し、2>&1で標準エラーも記録する
帯域制限(--bwlimit)で本番に影響を与えない
本番サーバーでrsyncを実行する場合、ネットワーク帯域を占有するとサービスに影響が出ます。--bwlimitで転送速度を制限できます。# 転送速度を5MB/sに制限 rsync -av --bwlimit=5000 /home/user/data/ user@192.168.1.100:/backup/data/
末尾スラッシュの挙動の違い
rsyncでは、同期元の末尾に「/」があるかないかで挙動が変わります。これを理解していないと、意図しないディレクトリ構造になります。# 末尾スラッシュあり → data/ の「中身」を /backup/data/ に同期 rsync -av /home/user/data/ /backup/data/ # 結果: /backup/data/file1.txt # 末尾スラッシュなし → data ディレクトリ自体を /backup/data/ の中に同期 rsync -av /home/user/data /backup/data/ # 結果: /backup/data/data/file1.txt
トラブルシュート・エラー対処
「Permission denied」が出た時の対処法
rsyncでPermission deniedが出る主な原因は以下の3つです。・同期先ディレクトリへの書き込み権限がない:sudo rsync で実行するか、同期先の権限を確認する
・SSH接続の認証失敗:公開鍵が正しく設定されているか、~/.ssh/authorized_keys を確認する
・SELinuxによるブロック:RHEL系ではSELinuxが書き込みを拒否する場合がある。/var/log/audit/audit.log を確認する
# 権限の問題を特定するために-vvで詳細表示 rsync -avvv /home/user/data/ /backup/data/ # sudoで実行する場合(リモート側でもsudoが必要な場合) rsync -av --rsync-path="sudo rsync" /home/user/data/ user@192.168.1.100:/backup/data/
「rsync: connection unexpectedly closed」の原因
このエラーはSSH接続が途中で切断された場合に発生します。主な原因は以下の通りです。・ネットワークの不安定:回線が途中で切れた場合。rsyncは再実行すれば差分から再開できる
・リモート側にrsyncがインストールされていない:接続先でrsyncコマンドが見つからない場合に発生する
・SSHの設定(タイムアウト):大量のファイル転送中にSSHセッションがタイムアウトする場合がある
# リモート側にrsyncがインストールされているか確認 ssh user@192.168.1.100 "which rsync" # SSHのタイムアウト対策(60秒ごとにKeepAliveを送信) rsync -av -e "ssh -o ServerAliveInterval=60" /home/user/data/ user@192.168.1.100:/backup/data/
【重要】--deleteの危険性と安全な使い方
--deleteは同期先のファイルを削除するため、使い方を誤ると取り返しのつかない事態になります。よくある事故パターンは、同期元のパスを間違えて空のディレクトリを指定してしまうケースです。この場合、同期先のファイルが全て削除されます。
# 危険な例:同期元を空ディレクトリにすると同期先が全削除される rsync -av --delete /tmp/empty/ /backup/data/ # → /backup/data/ の中身が全て消える
・手順1:まず--dry-runで削除対象を確認する
・手順2:削除対象が意図通りであることを目視確認する
・手順3:--dry-runを外して本実行する
# 手順1: --dry-runで確認(削除対象は「deleting」と表示される) rsync -avn --delete /home/user/data/ /backup/data/ # 手順2: 問題なければ--dry-runを外して実行 rsync -av --delete /home/user/data/ /backup/data/
# バックアップスクリプトの安全策 #!/bin/bash SRC="/home/user/data/" DEST="/backup/data/" # 同期元が存在し、かつ空でないことを確認 if [ -d "$SRC" ] && [ "$(ls -A $SRC)" ]; then rsync -a --delete "$SRC" "$DEST" else echo "ERROR: 同期元が存在しないか空です: $SRC" >&2 exit 1 fi
本記事のまとめ
rsyncの基本操作から実務で使うオプション、トラブル対処までを解説しました。以下にコマンド早見表をまとめます。| やりたいこと | コマンド |
|---|---|
| ローカルでディレクトリを同期 | rsync -av 同期元/ 同期先/ |
| リモートサーバーへ転送 | rsync -av 同期元/ user@host:同期先/ |
| リモートサーバーから取得 | rsync -av user@host:同期元/ 同期先/ |
| 事前確認(dry-run) | rsync -avn 同期元/ 同期先/ |
| 特定パターンを除外 | rsync -av --exclude="*.log" 同期元/ 同期先/ |
| 除外リストをファイルで指定 | rsync -av --exclude-from="ファイル" 同期元/ 同期先/ |
| 同期先の不要ファイルを削除 | rsync -av --delete 同期元/ 同期先/ |
| 転送速度を制限 | rsync -av --bwlimit=5000 同期元/ 同期先/ |
| 転送の進捗を表示 | rsync -av --progress 同期元/ 同期先/ |
| SSHポートを指定して転送 | rsync -av -e "ssh -p ポート番号" 同期元/ user@host:同期先/ |
rsyncでバックアップできるようになった、その先は?
rsyncによるファイル同期やバックアップは、サーバー運用の基本スキルの一つです。ここからさらに、ネットワーク設定やセキュリティ対策まで含めた全体像を身につけましょう。
ネットの切れ端の情報をコピペするだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
登録10秒/自動返信でDL/合わなければ解除3秒
