ディレクトリをコピーするときの挙動

rsync は source の後ろにスラッシュを付けるかどうかで挙動が変わる。
すなわち rsync -a source destrsync -a source/ dest は違う。

  • 前者だと source を dest にコピーしてくるという意味になるので dest/source ディレクトリができる
  • 後者だと source の中身を dest にコピーしてくるという意味になるので dest ディレクトリの中身と source ディレクトリの中身を一致させるように上書きする

特定のファイルタイプだけ処理したいとき

例えば jpeg だけコピーしたいなら、オプションとして --include='*/' --include='*.jpg' --exclude='*' のようにする。

なぜ?

rsync の処理フィルタについて、

  • フィルタオプションは先につけたものが優先される。
  • rsync は処理するかの判定をディレクトリ構造を下りながら逐一行いディレクトリが exclude された時点でそのディレクトリ内のファイルはすべて処理しない

というルールがあるためである。
なので上のように書くことで

  1. あらゆるディレクトリは必ず include する
    • このフィルタを付けて初めて全ファイルが検索対象になる
  2. *.jpg は必ず include する
  3. それ以外のファイルは exclude する

となり、所望の動作が達成できる。
例えば、 example/dir/file.jpg というファイルの場合、

  • ルール 1 により example/ は処理対象
  • ルール 1 により example/dir/ は処理対象
  • ルール 2 により example/dir/file.jpg は処理対象
  • ルール 3 により example/dir/file.png対象外

のようになる。
なお、対象のファイルがないディレクトリについてもルール 1 によりすべてコピーするため、空のディレクトリがたくさんコピーされてしまうがご愛敬。

参考記事

使用できる正規表現など、フィルタの使用についてより詳しく知るには rsync の複雑怪奇な exclude と include の適用手順を理解しよう - てっく煮ブログ を読む。

応用

シェルのブレース展開機能を使うと、--exclude={'*.jpg','*.png'} のようにすることで複数のファイルタイプを一括で排除できる。

バックアップをとるとき

オプションとして -ahH --info=progress2 としておけばよい。

  • -a: -rlptgoD に等しい
    • recursive
    • copy symlinks as symlinks
    • preserve permissions
    • preserve modification times
    • preserve group
    • preserve owner
    • preserve device and special files
  • -h: numbers in human-readable format
  • -H: ハードリンクを保持

進行度を正確に把握したいとき

--no-inc-recursive とすると、転送前に一度すべてのファイルのスキャンを行い、総転送量を把握したうえで全体の進捗を正確に表示する。

通信・ファイルアクセスが遅いとき

  • -z: ファイルデータを圧縮
  • -W: 増分アルゴリズムなしで全体をコピーする。ネット接続よりディスクアクセスが遅いときに有効