ネットワーク越しでもsshを通して更新ファイルだけ転送してくれるのでファイル単位のミラーリングが容易にとれるrsyncは何かと便利な一方、山のようにオプションがある上にオペレーションミスで即死するときがあるツールです。同一ホスト内で、挙動を確認してから実践しましょう。
練習環境の整備
同じ環境から試行錯誤した方が良いので、シェルスクリプトを書きます。
#!/bin/sh WORKDIR=/var/tmp/rsync SRC=${WORKDIR}/src DST=${WORKDIR}/dst INCLUDE=${WORKDIR}/include.lst EXCLUDE=${WORKDIR}/exclude.lst if [ -d ${WORKDIR} ]; then rm -fr ${WORKDIR} fi mkdir ${WORKDIR} mkdir ${SRC} mkdir ${SRC}/sub mkdir ${SRC}/sub/docs mkdir ${SRC}/docs mkdir ${DST} echo "a" > ${SRC}/a.txt echo "b" > ${SRC}/sub/docs/b.txt echo "c" > ${SRC}/docs/c.txt echo "*/docs\n" > ${INCLUDE} echo "docs\n" > ${EXCLUDE}
上のシェルスクリプトを実行したら、セットアップ完了です。
sh setup.sh
スクリプトが作成したファイルの存在と不存在を確認してみてください。
ls /var/tmp/rsync ls /var/tmp/rsync/src ls /var/tmp/rsync/src/docs ls /var/tmp/rsync/src/sub/docs ls /var/tmp/rsync/dst
rsyncを呼ぶシェルスクリプトを用意する
rsyncは定期的に呼ぶことが多いですし、ターミナルに直接打ち込むにはオプションが長くなりがちなので、シェルスクリプトを書いておきましょう。
#!/bin/sh if [ "$1" != "--dry-run" ] && [ "$1" != "-n" ] && [ -n "$1" ]; then echo "Error: the argument must be empty, --dry-run, or -n." > /dev/stderr exit 1 fi SRC=/var/tmp/rsync/src DST=/var/tmp/rsync/dst LOG=/var/tmp/rsync/rsync.log INCLUDE=/var/tmp/rsync/include.lst EXCLUDE=/var/tmp/rsync/exclude.lst SYNTAX="rsync $1 -av --delete --include-from=${INCLUDE} --exclude-from=${EXCLUDE} --log-file=${LOG} ${SRC}/ ${DST}" echo "CMD: $SYNTAX\n" > /dev/stderr $SYNTAX
-a は --recursive --links --perms --times --group --owner --devices と同等のオプションで、-v は監視モードで途中経過が出ます。
| オプション | 意味 |
|---|---|
| --recursive | 再帰的実行、つまりサブディレクトリー以下のファイルも対象にするオプションです。 |
| --links | シンボリックリンクを、リンク先のファイルではなくリンク自体としてコピーします。 |
| --perms | ファイルのパーミッションを保持します。 |
| --group | ファイルのグループIDを保持します。 |
| --times | 更新日時を保持します。 |
| --owner | ファイルのユーザーIDを保持します。 |
| --devices | デバイスファイルを保持します。 |
--ownerと--devicesはOS管理ユーザーでないと意味がないわけですが、他は無いと予想外の挙動になると思います。
| オプション | 意味 |
|---|---|
| --delete | 転送元に無いファイルは、転送先で削除する |
| --include= | 転送対象にするファイルパスのパターンを指定する |
| --include-from= | 転送対象にするファイルパスのパターンを書いたファイルを指定する |
| --exclude= | 転送対象外にするファイルパスのパターンを指定する |
| --exclude-from= | 転送対象外にするファイルパスのパターンを書いたファイルを指定する |
| --log-file= | ログファイルを指定する |
以上のオプションも実用上、つけることが多くなると思います。
--include-form(もしくは--include)と--exclude-from(--exclude)が無ければすべてのファイルとディレクトリーが転送対象で、それで間に合うことも多いと思いますが、一時ファイルなどを除外したい場合もそこそこあります。Linux Desktopの$HOMEを外付けドライブにバックアップを取るときなどは、.local/share/Trash/や.cache/などは無駄なので除外したいはずです。
--include-formと--exclude-fromを書く順番には気をつけてください。この順番に書いておくと、include指定したものは必ず含まれます。--includeと--excludeは複数並べられますが、ファイルにまとめた方が間違いが少ないと思います。
rsyncを試してみる
DRYRUN
ドライランから実行してみましょう。
sh rsync.sh --dry-run
CMD: rsync --dry-run -av --delete --include-from=/var/tmp/rsync/include.lst --exclude-from=/var/tmp/rsync/exclude.lst --log-file=/var/tmp/rsync/rsync.log /var/tmp/rsync/src/ /var/tmp/rsync/dst sending incremental file list a.txt sub/ sub/docs/ sub/docs/b.txt sent 170 bytes received 30 bytes 400.00 bytes/sec total size is 4 speedup is 0.02 (DRY RUN)
2ファイルと2ディレクトリが転送され、docs/c.txt が転送されないことが分かります。
なお、ドライランの短縮オプションは -n です。
最初の転送
実行してみましょう。
sh rsync.sh
CMD: rsync -av --delete --include-from=/var/tmp/rsync/include.lst --exclude-from=/var/tmp/rsync/exclude.lst --log-file=/var/tmp/rsync/rsync.log /var/tmp/rsync/src/ /var/tmp/rsync/dst sending incremental file list a.txt sub/ sub/docs/ sub/docs/b.txt sent 262 bytes received 70 bytes 664.00 bytes/sec total size is 4 speedup is 0.01
これでドライランの表示と同様に転送されました。
ファイルを更新して転送
作業前のファイルの中身を確認します。
cat /var/tmp/rsync/dst/a.txt
a
更新してrsyncを行いましょう。
echo "updated" > /var/tmp/rsync/src/a.txt sh rsync.sh
CMD: rsync -av --delete --include-from=/var/tmp/rsync/include.lst --exclude-from=/var/tmp/rsync/exclude.lst --log-file=/var/tmp/rsync/rsync.log /var/tmp/rsync/src/ /var/tmp/rsync/dst sending incremental file list a.txt sent 219 bytes received 37 bytes 512.00 bytes/sec total size is 12 speedup is 0.05
更新した a.txt だけが転送されました。
cat /var/tmp/rsync/dst/a.txt
updated
転送先ファイルが更新されたものになっています。
ファイルを追加して転送
ほぼ同じ作業ですが、ファイルを追加すれば、追加ファイルだけが転送されます。
echo "d" > /var/tmp/rsync/src/d.txt echo "e" > /var/tmp/rsync/src/docs/e.txt sh rsync.sh
CMD: rsync -av --delete --include-from=/var/tmp/rsync/include.lst --exclude-from=/var/tmp/rsync/exclude.lst --log-file=/var/tmp/rsync/rsync.log /var/tmp/rsync/src/ /var/tmp/rsync/dst sending incremental file list ./ d.txt sent 242 bytes received 40 bytes 564.00 bytes/sec total size is 14 speedup is 0.05
e.txtは除外ディレクトリーdocs以下にあるので、転送されていません。
ファイルを削除して転送
転送元の sub/docs/b.txt を削除して転送してみましょう。
rm /var/tmp/rsync/src/sub/docs/b.txt
sh rsync.sh
CMD: rsync -av --delete --include-from=/var/tmp/rsync/include.lst --exclude-from=/var/tmp/rsync/exclude.lst --log-file=/var/tmp/rsync/rsync.log /var/tmp/rsync/src/ /var/tmp/rsync/dst sending incremental file list deleting sub/docs/b.txt sub/docs/ sent 171 bytes received 35 bytes 412.00 bytes/sec total size is 12 speedup is 0.06
続けてディレクトリーsubも削除し、転送します。
rm -fr /var/tmp/rsync/src/sub sh rsync.sh
CMD: rsync -av --delete --include-from=/var/tmp/rsync/include.lst --exclude-from=/var/tmp/rsync/exclude.lst --log-file=/var/tmp/rsync/rsync.log /var/tmp/rsync/src/ /var/tmp/rsync/dst sending incremental file list deleting sub/docs/ deleting sub/ ./ sent 104 bytes received 36 bytes 280.00 bytes/sec total size is 12 speedup is 0.09
追加・更新・削除の挙動を確認しました。
sshを通じた転送
ssh接続元の /var/tmp/rsync/src から、ユーザー$userとしてssh接続先$hostname(e.g. hist.example.com, 192.168.22.45)の /var/tmp/rsync/src にファイルなどを転送する場合は、
rsync -av --delete --include-from=/var/tmp/rsync/include.lst --exclude-from=/var/tmp/rsync/exclude.lst --log-file=/var/tmp/rsync/rsync.log -e "ssh -i ${path_to_the_secret_key}" /var/tmp/rsync/src/ ${user}@${hostname}:/var/tmp/rsync/dst
と言う風になります。なお、scpと微妙に異なり、//varでなくて/varで済みます。
-e "ssh -i ${path_to_the_secret_key}"は秘密鍵を指定してsshを呼び出すと言うオプションで、デフォルトの秘密鍵でよい場合は省略できます。
CRONなどで動かす場合に秘密鍵のパスフレーズを無くしておきたい場合は、
ssh-keygen -p -f ${path_to_the_secret_key}でパスフレーズ再設定を行い、空欄とします。セキュリティーが緩くなるので、運用には気をつけましょう。
${user}@${hostname}は、~/.ssh/configに、例えば
Host host_rsync HostName host.example.com User user Port 22
と言うように設定されていれば、host_rsyncと書くだけで済みます。
rsync -av --delete --include-from=/var/tmp/rsync/include.lst --exclude-from=/var/tmp/rsync/exclude.lst --log-file=/var/tmp/rsync/rsync.log /var/tmp/rsync/src/ host_rsync:/var/tmp/rsync/dst
まとめと注意点
rsyncには山のようにオプションがあるので、もっと複雑な状況にも対処できますが、これぐらい把握しておくと使い始めやすいと思います。
転送元と転送先の指定を誤ってファイルを全部消したぐらいのトラブルしか経験はないのですが、