rsyncを使った熟練者レベルのバックアップ
rsyncのすばらしさはどこにあるのか。1つは、毎回ファイルを丸ごとコピーするのではなく、新旧ファイル間の差分をコピーすることでファイル転送を高速化している点だ。たとえば、この記事を書いているときも、rsyncで今すぐコピーを行い、後でまたコピーすることができる。2回目(あるいはそれ以降)にrsyncでこのファイルをコピーするときは、差分だけがコピーされる。そのため、所要時間はずっと短くて済む。これは、ディレクトリ全体を1日ごとにバックアップしたりする場合に特に重要だ。初回のコピーにはかなり時間がかかるが、次回以降はわずか数分で終わる(そのディレクトリの毎日の変更量があまり大きくなければの話だが)。
もう1つの利点は、rsyncではパーミッションおよび所有者情報の保存、シンボリックリンクのコピーが可能であり、全般的に各種ファイルをうまく処理するように作られていることだ。
わざわざrsyncをインストールする必要はないだろう。ほとんどどんなLinuxディストリビューションでもデフォルトで使えるようになっているはずだ。そうでなくても、ディストリビューションのパッケージリポジトリからインストールすることができる。言うまでもないが、リモートシステムにデータをコピーする場合はローカルとリモートの双方のマシンにrsyncが必要になる。
別のホストにファイルをコピーする場合、rsyncは、SSH(Secure Shell)やRSH(Remote Shell)のようなリモートシェル経由で動作する。以下の例ではSSHを利用するが、それはRSHがセキュアでなく、それをデータのコピーに使いたいと思う人は多分いないからだ。rsyncデーモンを使ってリモートホストに接続することも可能だが、最近はほぼどこでもSSHが使えるので、わざわざそうする必要はないだろう。
rsyncの使い方
rsyncの基本的な文法はかなりシンプルだ。単に「rsync [options] source destination
」とすれば、「 source
」で指定したファイル(複数可)が「 destination
」で指定した場所にコピーされる。
たとえば、ホームディレクトリの下にあるファイルをUSBストレージデバイスにコピーしたければ、「rsync -a /home/user/dir/ /media/disk/dir/
」とすればよい。ちなみに、rsyncは“/home/usr/dir/”と“/home/usr/dir”を区別する。最後のスラッシュがない場合、rsyncはそのディレクトリも含めて全体をコピーする。スラッシュがある場合、ディレクトリの中身をコピーするが、ディレクトリそのものは作られない。たとえば、/var/wwwを別のマシンか何かにミラーリングするなど、rsyncを使ってディレクトリ構造を複製しようとする場合は、最後のスラッシュを除く必要があるわけだ。
上の例では、アーカイブオプション(-a
)を指定している。これは、実際にはいくつかのrsyncオプションを結合したもので、再帰コピーとシンボリックリンクコピーの各オプションを含み、グループと所有者の情報を保存する。普通は、アーカイブのコピーに適したオプションだ。ただし、ハードリンクは保存されないので、それらも保存したい場合はハードリンクオプション(-H
)を追加する必要がある。
もう1つ、ほとんどの場合に必要になりそうなオプションが詳細情報の出力(-v
)で、これを使うとrsyncによって実行中の処理について多くの情報が表示される。このオプションは2つまたは3つ重ねることができる。つまり、-v
とするよりも-vv
とするほうが表示される情報は多く、-vvv
とすればrsyncの処理に関するすべての情報が表示される。
rsyncでは、オプションを何も指定しなくても隠しファイル(ファイル名が“.”で始まるもの)のコピーが行われる。隠しファイルを除外したければ、--exclude=".*/"
というオプションを使えばよい。また、--exclude
オプションを使ってVimのスワップファイル(.swp)や自動バックアップファイル(.bak)など一部のプログラムによって作成されたファイルをコピーの対象外にすることもできる。
ローカルコピーの実行
USBドライブまたはFireWireドライブがあれば、ホームディレクトリのデータをそうした外部ドライブにコピーしたいと考えるだろう。そのためのよい方法が、重要なデータを1つのトップレベルディレクトリにまとめておき、次のようなコマンドを使ってそのディレクトリを外部ドライブのバックアップディレクトリにコピーすることだ。
rsync -avh /home/usr/dir/ /media/disk/backup/
rsyncを最後に実行した後に削除したローカルファイルが、外部システムからも削除されるようにしたければ、次のように、--delete
オプションを追加する必要がある。
rsync -avh --delete /home/user/dir/ /media/disk/backup
ただし、--delete
オプションの使用にはくれぐれも注意すること。そのつもりがなくても大量のファイルを消してしまう恐れがある。実際、rsyncの使い方に慣れていても、いきなり実際にファイルのコピーや同期化を行うのではなく、--dry-run
オプションを使って転送内容の確認を行うとよいだろう。rsyncによる転送を開始してしまってから、コマンドのどこかに間違いがあってデータが破壊される危険があるとわかった場合は、すぐにCtrl-c
キーを押して転送を中止すること。一部は失われるだろうが、残りのファイルは救えるかもしれない。
リモートコピーの実行
手元にないファイルをリモートホストにコピーしたい場合はどうしたらよいだろうか。何も心配はいらない。コマンドにリモートホストとユーザの情報を追加するだけでよい。たとえば、先ほどのディレクトリをリモートホストにコピーしたければ、次のようにする。
rsync -avhe ssh --delete /home/user/dir/ user@remote.host.com:dir/
転送速度やコピーすべき残りファイル数を表示するには、次のように--progress
オプションを追加する。
rsync --progress -avhe ssh --delete /home/user/dir/ user@remote.host.com:dir/
rsyncによって接続が行われるたびにパスワードを訊かれたくなければ、パスワードではなくSSH鍵を使ってログインするようにrsyncを設定すればよい。そのためには、「ssh-keygen -t dsa
」を使ってローカルマシンでSSH鍵を生成し、パスワードの入力を求められたらEnterキーを押す。SSH鍵が生成されたら、「ssh-copy-id -i .ssh/id_dsa.pub user@remote.host.com
」を使って公開鍵をリモートホストにコピーする。
では、rsyncを使ってコピーしたファイルの一部を元に戻すにはどうすればよいか。次のコマンド構文を使えばよい。
rsync -avze ssh remote.host.com:/home/user/dir/ /local/path/
この例では、-z
オプションにより、データは圧縮された状態で転送される。コピー中のファイルがローカルホスト上に存在する場合、rsyncはそのファイルに対しては何も行わない。リモートホストにファイルをコピーするときと同じだ。
スクリプトにまとめる
同期させたいディレクトリがはっきりしていて、すべての同期に必要なコマンドがわかっているなら、それらをシンプルなスクリプトにまとめるのは容易だ。以下に簡単な例を示す。
rsync --progress -avze ssh --delete /home/user/bin/ user@remote.host.com:bin/ rsync --progress -avze ssh --delete /home/user/local/data/ user@remote.host.com:local/data/ rsync --progress -avze ssh --delete /home/user/.tomboy/ user@remote.host.com:/.tomboy/
--progress
オプションは、rsyncを対話的に実行するために使っているが、その必要がなければ削除して構わない。
rsyncのmanページを見ただけでは、きっと頭が混乱してしまうだろう。だが、こうして少しでもrsyncの使い方を実践しておけば、rsync処理の設定を行って、いつハードディスクが故障してもすぐにデータにアクセスできるように準備しておくことができるはずだ。