Saba note

醜悪コード Ugly hacks ITものづくり

rsyncの使い方

rsyncはとても便利です。開発環境の内容を一発で本番環境にアップロードするとかいうときにはとても便利です。Gitでpullするのもいいけどrsyncもいいです。各個人の開発環境からみんなで動作検証とかする開発ステージング環境へ反映するときはGitの方がいいけど、本番とミラーリングしているステージング環境なんかを本番に同期するにはrsyncの方がいい。というのはGitにはディレクトリパーミッションを保持する機能がないのです。rsyncにはあります。
またcronなんかで定期的に同期をとるにもrsyncはとてもいいです。更に双方のディレクトリの差分を事前にとることもできます。これはGitの方が便利かな。

基本的な使い方

rsync -a /from /to

ディレクトリを丸ごとコピーする際には、rsync -a [同期元] [同期先]でいいわけなんですが、基本的な使い方においてすでに奥が深いです。

rsync -a /from /to

の場合は、/to/fromという風にディレクトリが丸ごと/to/以下にコピーされます。しかし、

rsync -a /from/ /to

の場合は、/fromディレクトリの中身がそのまま/toディレクトリ以下に展開されます。fromディレクトリそのものはコピーされません。つまり、ディレクトリ以下を再帰的にコピーするというわけです。ここが基本的な使い方としてご注意。

rsync -a /from/ /to/

しかし、いろいろ複雑ですが、ディレクトリ以下を丸々同期かけるという設定だったら最後にスラッシュをつけた方が安全安心設定です。要は終端にスラッシュを付けておけばディレクトリ同士の同期をやってくれるというわけです。また、下記にある除外ファイルの設定がわかるとさらに楽になります。

削除したファイルも同期する

rsync -a --delete /from /to

–deleteオプションを使います。同期元で削除したファイルは同期先(コピー先)でも削除されます。ファイルが肥大化しなくていいです。同期というのだからたいていの場合は–deleteをつけて実行します。

同期する際に除外するファイルを指定する

例えばwordpressなんかですと、wp_config.phpとか、.htaccssはDBやサーバーパスの情報が入っているのでそのままコピーするとコピー先のサーバーではうごかなくなってしまいます。通常のファイルバックアップだったらそのままコピー保存で問題ありませんが、動的なファイルをそのまま同期すると設定ファイル類も上書きされて困ってしまいます。そういう場合は、同期の際に除外するファイルを指定します。

rsync -a --delete --exclude '.gvfs' /from /to

とこんな感じになります。同期先に指定したファイルは転送されません。
ここでちょっと注意なのは、除外ファイルはフルパスなどで設定する必要がないことです。/fromという同期元のパスが指定されているので、そのパスを基軸にして–exclude ‘PAHT’ということになります。これはなかなか便利だけど、時折迷います。
この–excludeオプションは正規表現も使えます。ドットファイルなどを同期したくない場合はまとめて正規表現で指定します。

rsync -a --delete --exclude ".*" /from /to

複数の全く別のファイルを除外する場合は、そのまま複数指定します。

rsync -a --delete --exclude "aaa.pl" --exclude "bbb.pl" --exclude "ccc.pl" /from /to

あまりにも除外ファイルがたくさんある場合は、除外ファイルリストを作成してそれを読みこませるということができます。

--exclude-from=ignore_list

ignore_listというファイルを作成して、同期元のディレクトリからの相対パスで、
.htaccessやその他の同期してほしくないファイルを改行で羅列してゆけばOKです。そういえば、ですが、–excludeを指定するファイルのパスはフルパスとか駄目です。あくまでもrsyncで設定した同期元のディレクトリを中心にそこからの相対パスで書きます。
しかももっとややこしいのが、たとえばconfig.phpなんていうファイルを無視すると同期元のディレクトリ以下すべてのconfig.phpが無視されます。ファイルの命名規則には要注意です。
こんなサービスもあります。
http://qiita.com/daimatz/items/f8c27d37052e2e573504

実行結果(実行内容)を詳細に表示させる

cronなんかで実行させるのだったらあんまり必要ないですが、端末でコマンド直叩きする場合だったら、その実行内容(同期をとったファイル(差異のあったファイル))のリストを一応見ておきたいものです。その時は、-vオプションを追加します。

rsync -av --delete /from /to

こんな感じです。

やたらと重いファイルは圧縮して送る

私もむかしはSCPコマンドでtarしたファイルを転送していました。SCPしてtarして結構面倒なのです。rsyncだったら圧縮して送信してその先で展開してくれるので便利。内部的な動作なので我々の目には見えませんが。重いファイルは圧縮して転送するのがよいです。-zオプションを使います。

rsync -avz --delete /from /to

SSHでリモート転送する

rsyncの醍醐味はやはりリモート転送なので、これは是非お試しください。バックアップを取るならリモートホスト感じゃないと本当は意味でないですし。SSHは非常に便利ですが、端末でコマンド直叩きの場合は通常のSSH接続で構わないですが、cronなどで実行する際にはパスワードなしの認証鍵を作らないとダメです。ここらの細かいSSHの解説は割愛しますが、全然わからないという人はSSHができるようになってからでので、sshの基本を学びましょう。
SSHを使う際には-eオプションを使います。

rsync -avz --delete -e "ssh username@example.com" /from /to

SSHの接続では手動でrsyncを使う場合は、パスワードがある秘密鍵を使うのでよいのだけど、たいていの場合はcronなどで自動的にバックアップをとっておくという仕組みを考えるわけでして、結局のところ-iオプションでパスワードなしの秘密鍵を指定するというのが大体のところなのではないかと。ポートの指定、秘密鍵の指定、SSHのバージョンと様々な細かい設定が必要な場合は以下のような感じになります。

rsync -avz --delete -e "ssh -i /home/user/.ssh/id_rsa" /from user@example.com:/to

ポートの設定とか鍵のパスとかSSHのバージョンとか暗号方式とかSSHのオプションはそのまま設定します。

rsync -avz --delete -e "ssh -i /home/user/.ssh/id_rsa -p 2222" /from user@example.com:/to

rsyncのオプション一覧

さてrsyncのオプションですが、これが実に様々なものがあります。rsyncでは-aを多用しますが、この-aはたいてい使われるオプションセットをまとめて設定するものです。以下よく使うオプションの一覧です。

Option functions
-v バックアップ中にコピーしているファイル名を表示する
-r 指定したディレクトリ以下を再帰的にコピーする
-l シンボリックリンクはそのままコピーする。指定しないとリンク先の実体がコピーされる
-H ハードリンクはそのままコピーする。指定しないとリンク先の実体がコピーされる
-p パーミッション属性をたもったままコピーする
-o 所有者属性をたもったままコピーする。指定しないと属性はコピーしたユーザーのものになる
-g グループ属性をたもったままコピーする。指定しないと属性はコピーしたユーザーのものになる
-t タイムスタンプをたもったままコピーする
-D デバイスファイルをたもったままコピーする
-z データを圧縮して転送する
-u 追加されたファイルだけをコピーする
-a 上記のオプションで「rlptgoD」を同時に指定する
–existing 更新されたファイルだけをコピーし、追加されたファイルは無視する
–delete コピー元で削除されたファイルは、コピー先でも削除する。-aオプションと同時に指定するとコピー元とコピー先を同期できる
–exclude ‘**’ **に一致するファイルはコピーしない。「.bak」「~」など特定のファイルを除外したいときに使う。この除外ファイルのパス指定は、rsyncの大元のディレクトリからの相対パスになります。
–stats コピーの結果を表示する。指定しないといっさいのメッセージは表示されない
–chmod rsync先の権限を変更するオプションを追加 –chmod=u+rwx |
-e ssh 暗号化してファイルを転送する。というかSSHで接続してrsyncする

変わり種としては–chmodなんていうのもある。コピー先(同期先)でのパーミションの調整ができるというものです。rsync Permission deniedになった時には有効です。オプションなどをいっぱいくっつけた実用的なコマンドというのは以下のようになるかもしれません。

rsync -avz --chmod=u+rwx --delete --exclude="wp-config.php" --exclude=".*" -e "ssh -i /home/user1/.ssh/id_rsa" /home/user/www/copy_dir user2@example.com:/home/user2/copyed_dir

長くてびっくりですが仕方ないです。これは、
まず-aでもって、再帰的にコピー、シンボリックリンクも同様にコピー、パーミッションを保ったままコピー、タイムスタンプも保持してコピー、グループを保持してコピー、オーナー権限も保持してコピー、デバイスファイルを保持してコピーということになります。
-vは実行中にそれぞれの作業を表示してくれるオプション。
それから、-zで転送データを圧縮して送るというオプション。これでだいたいのところは大丈夫です。バッチ処理的に行う場合は-vは必要ないかもです。
それから、パーミッションの問題が出てきたら–chmod=u+rwxでもってすべての権限を持たせてあげるのがいいです。
で、コピーしなくてもいいファイルが(上記の場合はWordpressの設定ファイルだけど)設定ファイル類、configファイル類だと思うので排除。また.htaccessとかの隠しファイル類もたいていの場合ホストごとに別の用途があると思われるので排除。
最後にSSH接続の設定を-eオプションで行うわけですが、この際、パスワードなしの秘密鍵認証を行います。予めパスフレーズなしの秘密鍵を生成してセットしておく必要があります。ここらはSSHの設定で個別にやっておく。
コピー元とコピー先のディレクトリ指定が間違っていないかどうか確認して終わり。

rsyncの諸々豆知識的注意点

–exclude=”xxxxx.php”とかやって同期除外設定をすると、再帰的にxxxxx.phpと同名のファイルが同期されなかったのでちょっとびっくりです。同期元・同期先のディレクトリをトップとして相対的にパスを指定するのかと思ったけど、全然そうじゃないです。こちら外部ファイルとして同期除外ファイルを設定できるので、できればそっちを使った方がいいですね。
reverse mapping checking getaddrinfo for [HOSTNAME] failed – POSSIBLE BREAK-IN ATTEMPT!というエラーみたいなものが出ることがあります。これは「接続元」のサーバーに正しいホスト名が設定されていないことが原因なので、/etc/hostsに[HOSTNAME]を加えてください。
送信先のサーバーにrsyncがインストールされていないとリモートホストでは使えません。もし送信先にインストールされていない場合は「bash: rsync: コマンドが見つかりません」というエラーが出ます。

rsyncで差分ファイルのリスト化をする(差分ファイルの確認)

差分をとってその差分ファイルをリスト化するだけ(同期しない)というのもできます。実際にコピーしないので確認作業にはとてもよいです。

rsync --checksum -nav -e ssh /home/user/data/ user@example.com:/home/user/data > diff.txt

みたいな感じです。オプションの-nをつけるのがポイントです。これ忘れると上書きされるのでご注意。ここでもパスの指定での最後のスラッシュに気をつけましょう。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です