2008年12月14日

rsyncで特定のファイルだけ転送する3

rsyncで特定のファイル、ディレクトリを除外して転送は--excludeオプションを指定すれば、事足りるんだけど、いくつかのディレクトリとかファイルとかだけ転送させたい。なんてことがあったりする。あんまり情報がないので、とりあえず書いとく。

よくあるのだと全てのディレクトリ、ファイル毎日rsyncしつつ、特定のディレクトリはバックアップを取らないみたいのが多いと思う
# /backupにごっそりバックアップ。けど特定のディレクトリは除外
rsync -av -H --delete --force --exclude="/backup/" --exclude="/dev/" --exclude="/proc/" --exclude="/sys/" / /backup
# とかリモートのサーバにバックアップとか
rsync -avz -H --delete --force --exclude="/backup/" --exclude="/dev/" --exclude="/proc/" --exclude="/sys/" / root@remote:/backup

これがたとえば特定のファイル、ディレクトリだけrsyncで別サーバに転送(同期)したい。例えばメールデータ(/var/spool/mail)、/etc/{passwd,shadow}、webコンテンツ(/var/www/{html,cgi-bin})、home(/home)だけもって行きたい場合。のメモ。転送先も同じディレクトリ構成とする。

実は悩むほどのことでもなかったりする。
至極単純に
# /var/spool/mail
rsync -avz --delete --force /var/spool/mail/ root@remote:/var/spool/mail
# passwd, shadow
rsync -avz --delete --force /etc/{passwd,shadow} root@remote:/etc
# web
rsync -avz --delete --force /var/www/{html,cgi-bin} root@remote:/var/www
# home
rsync -avz --delete --force /home/ root@remote:/home
と何回もrsyncすればそれで事足りるのだが、どうせなら一発で実行できるようにしたい。というわけで--include, --excludeオプションをうまく組み合わせてみる。
rsync -avv --delete --force --include="/var/" --include="/var/spool/" --include="/var/spool/mail/" --include="/etc/" --include="/etc/passwd" --include="/etc/shadow" --include="/var/" --include="/var/www/" --include="/var/www/html/" --include="/var/www/html/**" --include="/var/www/cgi-bin/" --include="/var/www/cgi-bin/**" --include="/home/" --include="/home/**" --exclude="*" / root@remote:/
かなり長ったらしくなったが、一応こんな感じでいける。--exclude="*"で全て除外にしつつも--includeで--excludeで除外しないファイル、ディレクトリを指定する。いきなり/var/spool/mail/などとしてもいけそうだけど、実はいけないので注意。/var/, /var/spool/, /var/spool/mail/ とか /var/, /var/www/, /var/www/html/, /var/www/html/**(*は/にもマッチする)のように指定する。めんどくさいけど。

でこれだとincludeに指定するファイル、ディレクトリがさらに多いとどうしようもなく見にくくなってしまうので、そんなときは
# for mail
+ /var/
+ /var/spool/
+ /var/spool/mail/

# for passwd, shadow
+ /etc/
+ /etc/passwd
+ /etc/shadow

# for web contents
+ /var/
+ /var/www
+ /var/www/html/
+ /var/www/html/**
+ /var/www/cgi-bin/
+ /var/www/cgi-bin/**

# for home
+ /home/
+ /home/**

# all exclude
- *
のようなファイルを作成して保存する。名前はなんでもいい。でrsync実行時に
rsync -avz --delete --force --exclude-from=/path/to/exclude / root@remote:/
--exclude-fromに作成したファイルを指定してあげればいい。このファイルは#で始まっている行、空行は無視してくれるから上記のようにコメントをいれることができる。これでrsync1回で実行可能になった。
実はssh + tarで同じようなことができるけど、こっちの場合は帯域制限がかけれないのと(--bwlimit=numで指定。単位はKB)、rsyncみたいに差分バックアップが難しいそうなので、今回は採用しないことにした。

ちなみに--dry-runオプションで実行せずにテストだけ先にできるので、いきなり実行しないようにしておくのが無難。

rsyncはよくできてると思うが、他にもっとスマートなやり方がありそうな気がする。
がまあいいか。いけたし。

追記:
何気にman rsyncを眺めてたら--files-fromなるオプションがあるそうな。
あらかじめ全てファイル、ディレクトリがわかっているならこっちのほうが楽かもしれない。標準入力からも指定できるからfindとかと組み合わせるといいかも。
Posted by kurt0027 at 03:00│Comments(1)TrackBack(0) I Love *NIX! 

この記事へのトラックバックURL

この記事へのコメント
ペットは特定は特定しなかったよ。
だけど、転送するはずだったみたい。
Posted by BlogPetのペット at 2008年12月16日 14:04

コメントする

名前
 
  絵文字