UNIX/Linuxの部屋 rsyncコマンドの使い方

TOP UNIX/Linuxの部屋 UNIX/Linuxコマンド一覧 用語集 新版 由来/読み方辞書 環境変数マニュアル Cシェル変数 システム設定ファイル システムコール・ライブラリ ネットワークプログラミングの基礎知識 クラウドサービス徹底比較・徹底解説




コマンド rsync ファイル・ディレクトリのバックアップ・ミラーリング・同期・転送 このエントリーをはてなブックマークに追加

最終更新


UNIX/Linux の rsync コマンドは、ファイル・ディレクトリのバックアップやミラーリング・同期処理を行うコマンドである。リモートサーバへの同期も可能である。また、差分のあるファイルのみを高速にミラーリングすることができる。rsync はフリーソフトウェアであり、FreeBSD/Linux などほとんどの UNIX 系 OS でパッケージが準備されているため、簡単に利用可能である。

ミラーリングやバックアップを行うだけなら cp コマンドでも実現可能だが、rsync コマンドには以下のようなメリットがある。
  • ミラーリングが可能 (単純な cp だと、削除されたファイルがコピー先に残ってしまう)
  • リモートサーバへの転送や、リモートサーバからの転送が可能
  • リモートサーバ接続において rsh や ssh に対応しているため、暗号化した上での転送が可能
  • 2回目以降の実行では、前回実行時との差分を調べ、必要なファイルのみ転送するため高速である


rsync コマンドの注意点 【2018/12/19 追加】
rsync コマンドはなかなかわかりづらいコマンドです。ディレクトリの末尾にスラッシュをつけるかつけないかで挙動が変わったり、--delete オプションで転送先から削除する機能があって、誤った指定をするとごっそりディレクトリが削除されたりします。

とにかくよくわからないうちは -n オプションをつけましょう。-n オプションは実際には転送や削除を行わず、どのような処理をするか表示するだけのオプションです。

rsync コマンドの基本的な使い方
もっとも基本的な使い方は、
% rsync -av /foo/from_dir /bar/to_dir
である。これはローカルマシン内の /foo/from_dir 以下を /bar/to_dir/ にコピーを行うもので、物理的な別ディスクにバックアップしたり、USB メモリなどに保存したりする場合に有用だろう。もし /bar/to_dir が存在していなくても、自動的に作成される。

なお、上記の結果、
/bar/to_dir/from_dir/...
というファイルが作成される。そうではなく from_dir 直下のファイルが to_dir 直下に作成してほしい場合は以下のように転送元ディレクトリの末尾にスラッシュを付ける (from_dir ではなく from_dir/ とする、ということ)。
% rsync -av /foo/from_dir/ /bar/to_dir

オプション -av の意味を説明する。-a を指定することで、rsync はアーカイブモードで動作するようになる。アーカイブモードとは頻繁に使用されるオプション群に名前を付けたもので、実際は -a は -rlptgoD と同じである。各オプションの意味は以下のとおり。
  • ディレクトリを再帰的にコピーする (-r)
  • シンボリックリンクを、そのままシンボリックリンクとしてコピーする (-l)
  • パーミッションをそのままコピーする (-p)
  • タイムスタンプをそのままコピーする (-t)
  • グループをそのままコピーする (-g)
  • ファイルオーナー (所有者) をそのままコピーする (-o)
  • デバイスファイルやを特殊ファイルを、そのままコピーする (-D)
-v は、コピーしたファイル名や、コピーしたバイト数などの転送情報を表示するオプションなので、慣れないうちは -v を指定した方が理解が早いだろう。

実行例
rsync を実行すると、以下のようにファイルコピーするファイル・ディレクトリを表示し、最後に転送量や転送速度などを表示する。
% rsync -av /foo/from_dir /bar/to_dir
building file list ... done

created directory to_dir
./
file.txt
program.c
(略)
sent 125706799 bytes received 117812 bytes 14802895.41 bytes/sec
total size is 125368532 speedup is 1.00

一度目の転送が完了したら、もう一度同じコマンドを実行してみよう。
% rsync -av /foo/from_dir /bar/to_dir
building file list ... done

sent 80627 bytes received 20 bytes 53764.67 bytes/sec
total size is 125368532 speedup is 1554.53
今度はあまり時間がかからずに終了したはずだ。rsync が from_dir と to_dir の差異をチェックし、転送すべきファイルは存在しないと判断したため、ファイルのコピーが行われなかったからである。

もし何かしらエラーが発生した場合は、最後のレポート部分に、さらに以下のようなエラー情報が表示される。
rsync error: some files could not be transferred (code 23) at main.c(977) [sender=2.6.9]

リモートへのコピー
rcp や scp などと同様に、転送先のディレクトリ指定にホスト名やユーザ名を付加すればよい。
% rsync -av /foo/from_dir/ example.com:to_dir/
→ example.com の to_dir/ に転送する。ユーザ名は、ローカルのユーザ名と同じものを使用する
% rsync -av /foo/from_dir/ user@example.com:to_dir/
→ example.com の to_dir/ にユーザ名 user で転送する。
% rsync -av -e ssh /foo/from_dir/ user@example.com:to_dir/
→ rsh でなく、ssh でログインする

上記の例はいずれも転送先がリモートホストの場合だったが、転送元がリモートホストでも問題ない。
% rsync -av -e ssh user@example.com:from_dir/ /foo/to_dir/
→ リモートからローカルへ転送する

オプションは以下のとおり。

表示系オプション
▷ -v または --verbose … コピーしたファイル名や、コピーしたバイト数などの転送情報を表示する。
-v オプションは複数個指定でき、-v より -vv の方が、さらに -vv より -vvv の方がより詳細な情報を表示する。
▷ -q または --quiet … 転送情報を表示しない。
▷ --stats : 転送後に、より詳細なファイル数・転送サイズを表示する。
Number of files: 5528
Number of files transferred: 15
Total file size: 125368532 bytes
Total transferred file size: 174602 bytes
Literal data: 0 bytes
Matched data: 0 bytes
File list size: 80611
File list generation time: 0.325 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 81077
Total bytes received: 800
▷ -h または --human-readable … バイト数などを読みやすい形で表示する。
通常の -v オプションでは、以下のような形のメッセージになる。
sent 125531503 bytes received 117812 bytes 7179960.86 bytes/sec
total size is 125368532 speedup is 1.00
これに -h オプションを付けると、キロバイト・メガバイト単位で表示するので少しだけ読みやすくなる。
sent 125.53M bytes received 117.81K bytes 4.12M bytes/sec
total size is 125.37M speedup is 1.00

情報保存系オプション
▷ -a または --archive … アーカイブモード。-rlptgoD を指定したのと同じ (-H が含まれていないことに注意)
具体的には下記オプションを全て指定したのと同じである。
  • -r: ディレクトリを再帰的にコピー
  • -l: シンボリックリンクを、そのままシンボリックリンクとしてコピー
  • -p: パーミッションをそのままコピー
  • -t: タイムスタンプをそのままコピー
  • -g: グループをそのままコピー
  • -o: ファイルオーナー (所有者) をそのままコピー
  • -D: デバイスファイルやを特殊ファイルを、そのままコピー
▷ -H または --hard-links … ハードリンクをそのまま反映する。
▷ -p または --perms … パーミッションをそのままコピーする。
▷ -E または --executability …
▷ --flags … ファイルフラグをそのままコピーする。
▷ -l または --links … シンボリックリンクを、そのままシンボリックリンクとしてコピーする。
▷ -t または --times … タイムスタンプをそのままコピーする。
▷ --devices … ブロックデバイスをコピーする (root のみ有効)
▷ --specials … 名前付きパイプや FIFO などの特殊ファイルをコピーする
▷ -D … "--devices --specials" と同じ
▷ -o または --owner … ファイル所有者をそのままコピーする (root で実行した場合のみ有効)
▷ -g または --group … グループをそのままコピーする
▷ -z または --compress … データ転送時に圧縮を行う
▷ --compress-level=NUM … 圧縮レベルを指定する

その他オプション
▷ -c または --checksum オプション
転送要否を決定する際、タイムスタンプとファイルサイズではなく、MD5 チェックサムを用いて同一ファイルか否かをチェックする。
▷ -r または --recursive オプション
ディレクトリを再帰的にコピーする。
▷ -R または --relative オプション
送信元のディレクトリ部分を、相対パスとして転送先に送信する。
% rsync -av /foo/bar/baz.c remote:/tmp/
→ 転送先には /tmp/baz.c として保存される。
% rsync -avR /foo/bar/baz.c remote:/tmp/
→ 転送先には /tmp/foo/bar/baz.c として保存される。
▷ -e または --rsh オプション
リモートサーバにログインする際に使用するコマンドを指定する。
% rsync -e ssh
または
% rsync --rsh="ssh"

最近の UNIX/Linux 環境の rsync コマンドではデフォルトで "-e ssh" としてコンパイルされているものが多いと思われる。また、下記のように ssh コマンドに引数を指定する場合にも使用可能である。
% rsync -e "ssh -p 10022"
または
% rsync --rsh="ssh -p 10022"
→ デフォルトのポート22 ではなくポート 10022 に接続する
▷ -u または --update オプション
転送先に既にファイルが存在し、転送先のタイムスタンプの方が新しい場合は転送しない
▷ -S または --sparse オプション
穴あきファイルを効率よく転送する
▷ -n または --dry-run オプション
コピーや転送を実際には行わず、行われる転送内容の出力のみ行う
▷ --list-only オプション
コピーや転送は行わず、転送対象となるファイルの表示のみ行う
▷ -W または --whole-file オプション
rsync アルゴリズムを使用せず、ファイル全体を転送する
▷ --existing または --ignore-non-existing オプション
転送先に存在しないファイルは転送対象外とする (新規ファイルの作成を行わない)
▷ --ignore-existing オプション
転送先に存在しているファイルは、転送対象外とする (新規ファイルの作成のみ行う)
▷ --remove-source-files オプション
転送に成功したファイルは転送元から削除する (ただしディレクトリは残す)
▷ --delete オプション
転送元に存在しないファイルが転送先に存在した場合、転送先から削除する
▷ --max-size=SIZE オプション
転送対象とするファイルサイズ上限を指定する。SIZE の例を以下に示す。
--max-size=2K (=2*1024)
--max-size=2M (=2*1024*1024)
--max-size=2G (=2*1024*1024*1024)
▷ --min-size=SIZE オプション
転送対象とするファイルサイズ下限を指定する
▷ -f, --filter=RULE オプション
add a file-filtering RULE
▷ --exclude=PATTERN オプション
指定したパターンにマッチするファイルを転送対象外とする。
例: --exclude="*.txt"
→ 拡張子 txt のファイルは転送対象外とする
▷ --bwlimit=KBPS オプション
帯域制御を行い、指定の速度以下で転送を行う (KBPS は KByte/秒 で指定)
例: --bwlimit=200
→ 200KBytes/秒 の帯域制御がかかる
▷ --modify-window=[しきい値の秒数] オプション
転送元・転送先の比較の際、タイムスタンプが指定秒数以内の違いであれば、違いがないものとみなす。デフォルトは 0 であり、ミリ秒以下が無視されることになる。これに 1 を指定すると、1秒以内の違いは同じとみなされる。また、-1 とすると秒単位で丸めずにナノ秒単位まで比較する。

rsync コマンドのタイムスタンプの比較方法 (秒単位・ナノ秒単位) 【2019/01/08追記】
rsync コマンドはデフォルトでは秒単位での比較を行う。つまりコンマ1秒の差異があったとしても、同じタイムスタンプとみなされる。よって、下記ような場合、ファイル内容に差異があるのに同期が行われない可能性がある。
  • 1秒以内に複数回の更新が行われる
  • ファイルサイズが変わらないような更新方法である
  • 更新と同時に rsync が同期を行っている

そのような場合、下記の選択肢がある。
  • 前述の --modify-window オプションにて --modify-window=-1 とし、ナノ秒単位まで比較する (ただし rsync 3.1.0 以降)
  • -c または --checksum オプションをつけて、タイムスタンプに頼らずブロック単位のチェックサムで差異を比較する。ただし、遅くなる。

関連コマンド
rsync と似たようなコマンドを紹介する。

同一サーバ内であれば cp コマンドを使う手がある。この場合、差分転送はできない。

また、tar cf して tar xf することでディレクトリごと同一サーバ内の別ディレクトリに複製を作ることができる。
% tar cf - -C source_dir | (cd /foo/bar tar xfp -)
さらに ssh 経由で他サーバに転送することもできる。
% tar zcf - -C source_dir | ssh user@remote.example.com 'tar xf - -C dest_dir'
いずれも差分転送はできない。

ファイルシステムとして zfs を使っている場合、zfs send | zfs recv で差分転送ができる。

rsync の起動タイミングをほぼリアルタイムにしたい場合は、lsyncd を活用するとよい。