「scpで毎回全ファイルをコピーしていて、転送に時間がかかりすぎる...」
Linuxでファイルやディレクトリを効率的に同期・転送するなら、
rsync コマンドが最適です。差分だけを転送するため、scpやcpと比べて圧倒的に高速で、バックアップの定番ツールとして現場で広く使われています。この記事では、
rsync コマンド の実践的な使い方を解説します。基本的なローカルコピーからリモートサーバーへのファイル転送、
--delete の安全な使い方、cronと組み合わせた自動バックアップまで、現場で使えるテクニックをまとめました。この記事のポイント
・rsync -avz でリモートサーバーへ差分だけ安全に転送できる
・--delete 前は必ず --dry-run (-n) で削除対象を確認する
・--exclude でログ・キャッシュを除外してスリムに同期する
・cronと鍵認証の組み合わせで無人自動バックアップを構築できる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
rsyncとは?(差分転送で高速にファイルを同期するコマンド)
rsync は「remote sync」の略で、ファイルやディレクトリを同期するためのコマンドです。最大の特徴は差分転送です。転送元と転送先を比較して、変更があったファイルだけを転送します。そのため、2回目以降のコピーが劇的に速くなります。
# rsyncの基本構文 rsync [オプション] 転送元 転送先
cp コマンドとの最大の違いは、rsync が「変更されたファイルだけ」を転送する点です。数GBのディレクトリでも、変更が数ファイルだけなら一瞬で同期が完了します。基本的な使い方(ローカルでのファイルコピー・同期)
まずはローカル環境でのコピーから見ていきましょう。rsyncはリモート転送だけでなく、ローカルのファイルコピーにも使えます。1. ファイルを1つコピーする
# ファイルを別のディレクトリにコピーする $ rsync access.log /backup/
cp コマンドとほぼ同じ動作です。rsyncの真価は、ディレクトリ単位の同期で発揮されます。2. ディレクトリを同期する(-aオプション)
ディレクトリごと同期する場合は、-a(archive)オプションを使います。パーミッション・所有者・タイムスタンプを保持したまま再帰的にコピーします。# ディレクトリを丸ごと同期する(パーミッションやタイムスタンプも保持) $ rsync -a /var/www/html/ /backup/html/
-a は -rlptgoD の省略形で、以下をまとめて指定しています。・-r:再帰的にコピー(サブディレクトリを含む)
・-l:シンボリックリンクをリンクのままコピー
・-p:パーミッションを保持
・-t:タイムスタンプを保持
・-g:グループを保持
・-o:所有者を保持(root権限が必要)
・-D:デバイスファイル・特殊ファイルを保持
実務では
rsync -a をベースに、必要なオプションを追加していくのが定番です。3. 進捗を表示する(-vと--progress)
転送状況を確認したい場合は、-v(verbose)や --progress を追加します。# 転送ファイル名と進捗を表示する $ rsync -av --progress /var/www/html/ /backup/html/ sending incremental file list index.html 12,845 100% 11.29MB/s 0:00:00 (xfr#1, to-chk=23/25) style.css 3,421 100% 3.26MB/s 0:00:00 (xfr#2, to-chk=22/25) sent 16,890 bytes received 54 bytes 33,888.00 bytes/sec total size is 16,266 speedup is 0.96
4. 末尾のスラッシュに注意(重要な落とし穴)
rsyncでは、転送元パスの末尾にスラッシュがあるかどうかで動作が変わります。これを知らないと意図しないディレクトリ構造になります。# スラッシュあり: htmlの「中身」を /backup/html/ に同期 $ rsync -a /var/www/html/ /backup/html/ # スラッシュなし: htmlディレクトリ自体を /backup/html/ 配下にコピー # 結果: /backup/html/html/ というディレクトリができる $ rsync -a /var/www/html /backup/html/
リモートサーバーへの転送(SSH経由のrsync)
rsyncの本領はリモートサーバーとのファイル同期です。SSH経由で安全にファイルを転送できます。1. ローカルからリモートへ転送する
# ローカルのディレクトリをリモートサーバーに転送する $ rsync -avz /var/www/html/ user@192.168.1.100:/backup/html/
-z オプションは転送データを圧縮します。ネットワーク越しの転送では、帯域の節約になるため付けるのが一般的です。2. リモートからローカルへ取得する
# リモートサーバーからファイルを取得する $ rsync -avz user@192.168.1.100:/var/log/httpd/ /backup/httpd-logs/
3. SSHポートを指定する(-eオプション)
SSHのポート番号がデフォルトの22以外の場合は、-e オプションで指定します。# SSHポート2222を使ってリモートに転送する $ rsync -avz -e "ssh -p 2222" /var/www/html/ user@192.168.1.100:/backup/html/
4. 秘密鍵(PEMファイル)を指定する(AWS EC2向け)
AWS EC2や鍵ファイルを使うサーバーに接続する場合は、-e オプションで鍵ファイルを指定します。# PEM鍵ファイルを指定してEC2にファイルを転送する $ rsync -avz -e "ssh -i ~/.ssh/mykey.pem -o StrictHostKeyChecking=no" /var/www/html/ ec2-user@ec2-xxx-xxx.compute.amazonaws.com:/backup/html/ # 取得方向: EC2からローカルに取得する場合 $ rsync -avz -e "ssh -i ~/.ssh/mykey.pem" ec2-user@ec2-xxx-xxx.compute.amazonaws.com:/var/log/httpd/ /backup/httpd-logs/
StrictHostKeyChecking=no は初回接続時のホスト確認プロンプトをスキップします。スクリプトで自動実行する場合に便利ですが、セキュリティ要件の厳しい環境では ~/.ssh/known_hosts に事前登録する方法を検討してください。実務で使うオプション一覧
rsyncのオプションは非常に多いですが、実務で使うものは限られています。よく使うオプションをまとめます。・-a:アーカイブモード(パーミッション・所有者・タイムスタンプ保持)
・-v:転送ファイル名を表示する
・-z:転送データを圧縮する(リモート転送時に有効)
・--progress:転送の進捗を表示する
・--delete:転送元にないファイルを転送先から削除する
・--exclude:指定したパターンのファイルを除外する
・--dry-run(-n):実際には転送せず、何が起こるかだけ表示する
・--backup(-b):上書きされるファイルのバックアップを作成する
・--partial:転送中断後に再開する(中途ファイルを保持する)
・--bwlimit:転送帯域を制限する(単位はKB/s)
・--checksum(-c):タイムスタンプではなくチェックサムで差分を判定する
・-e:リモートシェルを指定する(SSHポート変更・鍵ファイル指定時など)
特に
--delete と --dry-run は使い方を間違えるとデータを失う可能性があるため、次のセクションで詳しく解説します。--deleteの安全な使い方(転送先の不要ファイルを削除する)
--delete オプションは、転送元に存在しないファイルを転送先から削除します。完全なミラーリングを行いたい場合に使いますが、使い方を誤ると転送先のファイルが消えます。1. まず--dry-runで確認する(鉄則)
--delete を使う前に、必ず --dry-run(または -n)で何が削除されるか確認してください。# 実際には実行せず、何が起きるかだけ表示する $ rsync -avn --delete /var/www/html/ /backup/html/ sending incremental file list deleting old-page.html deleting temp/debug.log sent 245 bytes received 12 bytes 514.00 bytes/sec total size is 156,890 speedup is 614.23 (DRY RUN)
(DRY RUN) が表示されていれば、実際の転送は行われていない証拠です。「deleting」と表示されたファイルが削除対象になります。意図しないファイルが含まれていないか、必ず目視で確認しましょう。2. --deleteを実行する
--dry-run で問題がなければ、-n を外して実行します。# 転送元にないファイルを転送先からも削除する(完全同期) $ rsync -av --delete /var/www/html/ /backup/html/ sending incremental file list deleting old-page.html deleting temp/debug.log index.html sent 13,156 bytes received 89 bytes 26,490.00 bytes/sec total size is 156,890 speedup is 11.85
【重要】--deleteの危険性
--delete で転送元のパスを間違えると、転送先のファイルが全て削除される可能性があります。# 危険な例: 空ディレクトリを転送元にすると、転送先が全削除される $ rsync -av --delete /tmp/empty/ /backup/html/ # /backup/html/ の全ファイルが削除される!
/backup/html/ 内の全ファイルが削除されます。--delete は必ず --dry-run とセットで使うことを習慣にしてください。除外設定(--excludeで特定ファイルをスキップする)
ログファイルやキャッシュなど、同期不要なファイルを除外する方法です。1. パターンで除外する
# .logファイルを除外して同期する $ rsync -av --exclude="*.log" /var/www/html/ /backup/html/ # 複数のパターンを除外する $ rsync -av --exclude="*.log" --exclude="*.tmp" --exclude="cache/" /var/www/html/ /backup/html/
2. 除外リストをファイルで管理する(--exclude-from)
除外パターンが多い場合は、ファイルにまとめて管理すると便利です。# 除外リストファイルを作成する $ cat /etc/rsync-exclude.txt *.log *.tmp cache/ .git/ node_modules/ # 除外リストを指定して同期する $ rsync -av --exclude-from="/etc/rsync-exclude.txt" /var/www/html/ /backup/html/
3. 除外と含めるを組み合わせる(--includeと--exclude)
「特定ディレクトリ内の.logだけ除外し、それ以外は含める」といった細かい制御も可能です。# .confファイルだけを同期し、他はすべて除外する $ rsync -av --include="*.conf" --exclude="*" /etc/httpd/ /backup/httpd-conf/ # 特定ディレクトリ配下のlogだけ除外する(ディレクトリは含める) $ rsync -av --exclude="logs/*.log" /var/www/html/ /backup/html/
--include と --exclude は記述順に評価されます。より具体的なルールを先に書くのが基本です。大容量ファイル転送のTips(--bwlimit / --partial)
本番サーバーへの転送や、長時間かかる大容量データの同期では、以下のオプションが役立ちます。1. 帯域を制限する(--bwlimit)
本番環境でrsyncを実行するとき、帯域を使い切って業務に影響が出ることがあります。--bwlimit で転送速度の上限を設定しましょう。# 転送速度を1MB/s(1000KB/s)に制限する $ rsync -avz --bwlimit=1000 /var/www/html/ user@192.168.1.100:/backup/html/ # 10MB/s(10000KB/s)に制限する場合 $ rsync -avz --bwlimit=10000 /large-data/ user@backup-server:/storage/
--bwlimit=1000(1MB/s)程度を目安にするとサービスへの影響を最小限に抑えられます。2. 転送を中断・再開する(--partial)
大容量ファイルの転送中にネットワーク障害で中断した場合、--partial を付けておくと転送済みの部分が保持され、再実行時に途中から再開できます。# 中断後も部分転送ファイルを保持する $ rsync -avz --partial /large-backup.tar.gz user@192.168.1.100:/storage/ # --partial と --progress を組み合わせて進捗付きで再開可能にする $ rsync -avz --partial --progress /large-backup.tar.gz user@192.168.1.100:/storage/ large-backup.tar.gz 524,288,000 45% 3.21MB/s 0:02:41
-P オプションは --partial --progress をまとめた短縮形です。大容量ファイルを転送する場面では rsync -avzP がよく使われます。3. チェックサムで完全一致を確認する(--checksum)
rsyncは通常、タイムスタンプとファイルサイズで差分を判断します。タイムスタンプが変更されていても中身が同じファイルを再転送したくない場合や、逆にタイムスタンプが変わっていなくても内容の変更を確実に検知したい場合に使います。# タイムスタンプでなくチェックサム(MD5)で差分を判定する $ rsync -avc /var/www/html/ /backup/html/
--checksum(-c)はファイルごとにMD5チェックサムを計算するため、通常より処理が重くなります。本当に必要な場面(データ移行後の整合性確認など)に限定して使うのが現場の慣例です。cronと組み合わせた自動バックアップ(定期実行の設定方法)
rsyncの真価は、cronと組み合わせて自動バックアップを構築したときに発揮されます。手動で毎回コマンドを打つ必要がなくなり、深夜帯に差分だけを転送する運用が実現できます。1. バックアップスクリプトを作成する
まず、rsyncコマンドをシェルスクリプトにまとめます。直接crontabにコマンドを書くより、スクリプト化しておく方が管理しやすく、ログ出力も柔軟に設定できます。# バックアップスクリプトを作成する $ vi /usr/local/bin/backup-web.sh #!/bin/bash # Webサーバーのバックアップスクリプト LOG="/var/log/rsync-backup.log" echo "--- Tue Apr 21 16:59:57 JST 2026 ---" >> "" rsync -avz --delete --exclude="*.log" --exclude="*.tmp" /var/www/html/ user@192.168.1.100:/backup/html/ >> "" 2>&1 echo "exit: 0" >> "" # 実行権限を付与する $ chmod 755 /usr/local/bin/backup-web.sh
2. crontabに登録する
スクリプトが動作することを確認したら、crontabに登録して定期実行を設定します。# crontabを編集する $ crontab -e # 毎日午前3時にバックアップを実行する 0 3 * * * /usr/local/bin/backup-web.sh # 6時間ごとに実行する場合 0 */6 * * * /usr/local/bin/backup-web.sh
3. SSH鍵認証を設定する(パスワード入力なしで接続)
cronで自動実行する場合、パスワード入力ができません。SSH鍵認証を事前に設定しておく必要があります。# SSH鍵を生成する(パスフレーズなし) $ ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_backup -N "" Generating public/private rsa key pair. Your identification has been saved in /root/.ssh/id_rsa_backup Your public key has been saved in /root/.ssh/id_rsa_backup.pub # 公開鍵をリモートサーバーに登録する $ ssh-copy-id -i ~/.ssh/id_rsa_backup.pub user@192.168.1.100 Number of key(s) added: 1 # 接続確認 $ ssh -i ~/.ssh/id_rsa_backup user@192.168.1.100 "hostname" backup-server
-e オプションを使います。# スクリプト内で鍵ファイルを指定する場合 rsync -avz -e "ssh -i /root/.ssh/id_rsa_backup" --delete /var/www/html/ user@192.168.1.100:/backup/html/
【重要】cron実行時の注意点
cronで実行する場合、ログイン時とは環境変数が異なります。以下の点に注意してください。・PATHが通っていない:rsyncのフルパス(
/usr/bin/rsync)を使うか、スクリプト冒頭で PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin を明示する・ログを必ず残す:cronはデフォルトで標準出力を捨てるため、スクリプト内でログファイルに出力する
・動作確認を先にする:crontabに登録する前に、手動でスクリプトを実行して正常に動くことを確認する
・終了コードを記録する:スクリプト末尾に
echo "exit: 0" を加えておくと異常終了の検知に役立つトラブルシュート・エラー対処
rsyncで遭遇しやすいエラーと対処法をまとめます。「Permission denied」が出た時の対処法
リモートサーバーへの転送時に権限エラーが出る場合は、以下を確認してください。# SSH鍵の権限を確認する $ ls -l ~/.ssh/id_rsa -rw-------. 1 user user 1675 3月 15 10:00 /home/user/.ssh/id_rsa # 権限が正しくない場合は修正する $ chmod 600 ~/.ssh/id_rsa $ chmod 700 ~/.ssh/
・
~/.ssh/ ディレクトリ自体が700になっているか・転送先ディレクトリへの書き込み権限があるか
・
-a オプションで所有者を保持する場合はroot権限が必要「rsync: connection unexpectedly closed」の対処法
転送中に接続が切れる場合は、以下が原因であることが多いです。# リモートサーバーにrsyncがあるか確認する $ ssh user@192.168.1.100 "which rsync" /usr/bin/rsync # ディスク容量を確認する $ ssh user@192.168.1.100 "df -h /backup" Filesystem Size Used Avail Use% Mounted on /dev/xvdb 50G 35G 15G 70% /backup
・ファイアウォールでSSHポートがブロックされている
・転送先のディスク容量が不足している
・長時間の転送でSSHセッションがタイムアウトした(
-o ServerAliveInterval=60 を追加して対処)「rsync error: some files could not be transferred」の対処法
一部のファイルだけ転送に失敗する場合は、読み取り権限がないファイルが含まれている可能性があります。# sudoを付けて全ファイルにアクセスする $ sudo rsync -av /var/www/html/ /backup/html/ # 権限エラーのファイルだけ確認する(-v で詳細を確認) $ rsync -av /var/www/html/ /backup/html/ 2>&1 | grep "Permission denied"
「No space left on device」が出た時の対処法
転送先のディスクが満杯のときに発生します。--bwlimit 追加前に必ずディスク空き容量を確認してください。# 転送先のディスク使用量を確認する $ df -h /backup Filesystem Size Used Avail Use% Mounted on /dev/xvdb 50G 50G 0 100% /backup # 古いバックアップを削除してから再実行する $ find /backup -name "*.bak" -mtime +30 -delete $ rsync -avz /var/www/html/ user@backup-server:/backup/html/
「rsync: [sender] write error: Broken pipe」の対処法
ネットワークが不安定な環境で大容量ファイルを転送中に発生しやすいエラーです。--partial と組み合わせることで、切断後に途中から再開できます。# --partial で中断後に再開可能にする $ rsync -avzP --timeout=60 /large-data/ user@192.168.1.100:/backup/ # --timeout: 転送停止状態が続いた場合のタイムアウト秒数 # 不安定な回線では 30~120 秒程度が目安
転送後にファイル数が合わない時の確認方法
転送完了後、件数がおかしいと感じたら以下のコマンドで確認できます。# 転送元と転送先のファイル数を比較する $ find /var/www/html/ -type f | wc -l 1,247 $ find /backup/html/ -type f | wc -l 1,247 # --checksum で内容の整合性まで検証する(差異があるファイルを一覧表示) $ rsync -avcn /var/www/html/ /backup/html/ | grep -v "^sending"
本記事のまとめ
| やりたいこと | コマンド |
|---|---|
| ファイルを1つコピーする | rsync ファイル名 転送先/ |
| ディレクトリを同期する(基本) | rsync -av 転送元/ 転送先/ |
| リモートサーバーに転送する | rsync -avz 転送元/ user@host:転送先/ |
| リモートからファイルを取得する | rsync -avz user@host:転送元/ 転送先/ |
| PEM鍵を使ってEC2に転送する | rsync -avz -e "ssh -i key.pem" 転送元/ user@host:転送先/ |
| SSHポートを指定して転送する | rsync -avz -e "ssh -p 2222" 転送元/ user@host:転送先/ |
| 実行前に確認する(ドライラン) | rsync -avn --delete 転送元/ 転送先/ |
| 転送先の不要ファイルを削除する | rsync -av --delete 転送元/ 転送先/ |
| 特定ファイルを除外する | rsync -av --exclude="*.log" 転送元/ 転送先/ |
| 除外リストファイルを使う | rsync -av --exclude-from="/etc/exclude.txt" 転送元/ 転送先/ |
| 転送帯域を制限する(1MB/s) | rsync -avz --bwlimit=1000 転送元/ user@host:転送先/ |
| 中断後に途中から再開する | rsync -avzP 転送元/ user@host:転送先/ |
| チェックサムで整合性確認する | rsync -avcn 転送元/ 転送先/ |
| cronで毎日自動バックアップする | 0 3 * * * /usr/local/bin/backup-web.sh |
rsyncで自動バックアップを組み、「もしも」に備えたサーバー運用を実現しませんか?
差分転送・--delete・cronとの連携まで、rsyncを使いこなせばバックアップ運用は一段と安定します。
ネットの切れ端の情報をコピペするだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます