WebOS Goodies

WebOS の未来を模索する、ゲームプログラマあがりの Web 開発者のブログ。

WebOS Goodies へようこそ! WebOS はインターネットの未来形。あらゆる Web サイトが繋がり、共有し、協力して創り上げる、ひとつの巨大な情報システムです。そこでは、あらゆる情報がネットワーク上に蓄積され、我々はいつでも、どこからでも、多彩なデバイスを使ってそれらにアクセスできます。 WebOS Goodies は、さまざまな情報提供やツール開発を通して、そんな世界の実現に少しでも貢献するべく活動していきます。
Subscribe       

高機能なファイル同期ツール rsync の使い方

最近、 Infosketch の開発などで rsync を利用する機会が増えてきました。 rsync はネットワーク経由のコピーも可能なファイル・ディレクトリ同期ツールで、コマンドひとつでディレクトリツリーを一気に転送できるほか、差分のみの転送やコピー対象の条件指定といった多彩な機能を搭載しています。 rsync という名前に反してローカル間のコピーも可能で、 make ファイル内でデータディレクトリを丸ごとコピーするといった用途にも便利に使えます。

けっこうメジャーなツールなので既にバリバリに活用されている方も多いと思いますが、自分用のメモも兼ねて使い方をまとめてみました。まだお使いでない方は、これを機会にぜひ試してみてください。また、既に使われている方もチートシート的に活用していただければと思います。

rsync とは

前述のとおり、 rsync はローカル・リモート問わずに利用できる高機能なファイル・ディレクトリ同期ツールです。変更分を自動的に検出して差分のみを転送するため、ネットワーク経由でも効率的にファイル同期が行えるのが最大の特徴です。その他の主な特徴は以下のとおりです。

  • 特別な設定や管理情報などが必要なく、手軽に使える。
  • SSH を利用することでセキュアなファイル転送を実現。
  • 転送条件などをきめ細かく指定できる。
  • コマンドラインツールなので、自動化・バッチ処理にも最適。
  • デーモンとして起動することで、匿名アクセスにも対応可能。ただし、この記事ではデーモンモードの情報は割愛しています。ご了承ください m(_ _)m

ほとんどの Linux ディストリビューションには標準で含まれていると思います。 Windows 向けには cwRsync というネイティブ実装が存在するほか、 Cygwin にも標準で含まれていますので、ほとんどの環境で手軽に導入できると思います。

基本的な使い方

rsync の基本的な書式は cp コマンドなどと同じです。

rsync [オプション] コピー元 [コピー元...] コピー先

コピー元、コピー先ともにローカルパスを指定すればローカルファイル間のコピーになりますし、 "[ユーザー名@]ホスト名:パス" の書式でリモートのパスを指定すればネットワーク経由でのコピーとなります。例えば、以下のコマンドを実行すると、ディレクトリ foo 以下のツリー全てをリモートホスト remote.example.com の /tmp 以下にコピーします。このとき、ディレクトリの最後に "/" を付けるかどうかで挙動が変わりますのでご注意ください(詳細は後述)。

rsync -r foo remote.example.com:/tmp

リモートホスト同士の転送はできませんので、少なくともコピー元かコピー先のどちらか一方はローカルパスである必要があります。また、ホスト名で指定するリモートホストには以下の条件を満たさなければなりません。

  • SSH サーバーが起動している。
  • ユーザー名 で指定したユーザー(もしくはローカルと同じユーザー名)で SSH ログインが可能になっている。
  • リモート側にも rsync がインストールされている。

基本的な使い方はこれだけです。リモートにも転送できる cp コマンドという感じで、簡単に使えるのがおわかりいただけると思います。さらに次でご紹介するオプションを活用することで、コピーするファイルの条件やコピー時の挙動を自由に変更できますので、さまざまな目的に対応できるようになっています。

コマンドラインオプション

rsync には、コピーの挙動を制御するための多数のコマンドラインオプションが用意されています。その全てを挙げるのはたいへんなので、よく使いそうなものを独断と偏見でピックアップして表にしてみました。

コピー対象とするファイルの条件を指定するオプション

オプション 機能
-r--recursive ディレクトリを再帰的にコピー
-u--update コピー先がコピー元より新しいならコピーしない
--existing コピー先に存在するファイルのみ更新
--ignore-existing コピー先に存在するファイルは更新しない
-I--ignore-times サイズと日付が同じでもスキップしない
-C--cvs-exclude .svn, *.o, *.bak...などをコピーしない
--exclude=PATTERN PATTERN にマッチするファイルを除外
--include=PATTERN PATTERN にマッチするファイルを除外しない
-m--prune-empty-dir 空ディレクトリをコピーしない

コピーの挙動を制御するオプション

オプション 機能
-l--links symlink をそのままコピー
-L--copy-links symlink のリンク先をコピー
--copy-unsafe-linksツリー外を指す symlink のみリンク先をコピー
--safe-links ツリー外を指す symlink をコピーしない
-H--hard-links ハードリンクを維持する
-p--perms アクセス許可属性を維持する
-E--executability 実行許可属性を維持する
--chmod=CHMOD アクセス許可属性を指定する
-o--owner 所有者を維持する
-g--group グループを維持する
--numeric-ids uid/gid を名前でマッピングしない
-t--time 作成時刻などを維持する
-W--whole-file 差分転送せずにファイル全体をコピー

その他のオプション

オプション 機能
--delete コピー元にないファイルをコピー先から削除する
--force 空でないディレクトリも削除する
-n--dry-run コピーを実行せずに処理内容を表示
-e--rsh=COMMAND ファイル転送に COMMAND を使う
-z--compress 転送データを圧縮する
--compress-level=N 圧縮率を指定する
-a--archive -rlptgoD と同じ
--progress 転送の進捗を表示
-v--verbose 詳細なメッセージを表示
-q--quite エラー以外のメッセージを表示しない

このくらいを押さえてあれば、たいていの用途には対応できるでしょう。さらに詳しい情報は man ページなどを参照してください。

その他の情報

上記の表の説明でほとんどのオプションは使い方がわかると思いますが、なかには多少複雑なものもあります。それらの説明を中心にして、補足的な情報を以下にまとめておきます。

ディレクトリの最後の "/" の意味

先ほども少し触れましたが、 rsync ではコピー元のディレクトリ名の最後に "/" を付けるかどうかで挙動が変わります。例えば、先ほどの例の場合。

rsync -r foo remote.example.com:/tmp

この場合は、 "/tmp/foo" が作成され、その中に "foo" 以下のファイル・ディレクトリが再帰的にコピーされます。それに対して、以下のように "/" を付けた場合。

rsync -r foo/ remote.example.com:/tmp

この場合は "foo" ディレクトリが作成されず、 "/tmp" 直下に "foo" の中身が再帰的にコピーされます。というわけで、

  • ディレクトリそのものをコピーしたい場合 → "/" なし
  • ディレクトリ以下のツリーをコピーしたい場合 → "/" あり

なお、コピー先は "/" があってもなくても動作に違いはありません。

--exclude, --include のパターンの指定方法

--exclude, --include は、指定した条件にマッチするファイルをコピー対象から除外する(もしくは除外しない)ためのオプションです。これらのオプションは何回でも指定でき、順番にテストして最初にマッチしたものが --exclude であればコピー対象から除外され、 --include であれば除外されません。いずれのパターンにもマッチしなければ、やはり除外されません。

パターンはシェルのワイルドカードと同じような感じで指定します。

記号 機能
* "/" を除くすべての文字の 0 回以上の繰り返しにマッチする
? "/" を除くすべての文字にマッチする
[ ] シェルと同様の文字クラス
** "/" を含むすべての文字の 0 回以上の繰り返しにマッチする

さらに、追加で以下の規則が適用されます。

  • マッチ対象となるパス名は、コピー元が "/" で終わる場合はコピー元ディレクトリそのもの、そうでなければコピー元ディレクトリの親がルートになります。例えば、ファイルのフルパスが "/foo/bar" であるとき、コピー元が "/foo/" ならマッチ対象パス名は "/bar" となり、同様に "/foo" なら "/foo/bar" となります。
  • パターンが "/"(先頭・末尾を除く) や "**" を含まない場合、パスの最後のコンポーネントのみがマッチ対象になります。
  • パターンが "/" で終わる場合、ディレクトリ以外にはマッチしなくなります。
  • パターンが "/" で始まる場合、パス全体がマッチ対象になります。パターン "/fo*" は、 "/foo" にマッチしますが、 "/bar/foo" にはマッチしません。
  • パターンが "/"(先頭・末尾を除く)か "**" を含む場合、パスのすべてのコンポーネントがマッチ対象になります。例えば、パターン "foo/bar" は "/foo/bar/baz" と "/baz/foo/bar" の両方にマッチします。
  • "foo/***" は、 "foo" 自身とそれ以下のすべてのファイルにマッチする特殊なパターンです。バージョン 2.6.7 以降で使えます。
  • ワイルドカードの記号は直前にバックスラッシュ(円マーク)を付けることでエスケープできます。

ちょっと複雑ですね。 --dry-run オプションを付けて実行するとコピーを行わずにコピー対象となるファイルを確認できますので、それでいろいろと実験してみるのが良いかと思います。実は --include / --exclude よりも高機能な --filter というオプションもあるのですが、そちらに関しては man ページをご参照ください。たいていは --include / --exclude で間に合うと思います。

--chmod の使い方

--chmod オプションを使うと、転送ファイルのパーミッションを自由に制御できます。パラメータの指定方法は基本的にシェルの chmod コマンドと同じです。例えば、以下のように指定すると所有者に対して読み書きを、グループに対して読み込みを許可します。

rsync --chmod=u+rw,g+r src dst

さらに、各パーミッション指定の先頭に 'D' もしくは 'F' をつけると、それぞれディレクトリのみ、ファイルのみに適用されます。例えば以下の指定はディレクトリのみに実行属性を付加します。

rsync --chmod=Da+x src dst

なお、コピー先に既に存在するファイルに対しては、 --perms オプションを併用しないと --chmod の効果が顕れないので、ご注意ください。

以上、本日はコマンドラインのディレクトリ同期ツール rsync の使い方をご紹介しました。とくにリモートサーバーとの間で安全・効率的にファイルを転送する手段として、とても便利に使えると思います。皆さんぜひ活用してください!

関連記事

この記事にコメントする

Recommendations
Books
「Closure Library」の入門書です。
詳しくはこちらの記事をどうぞ!
Categories
Recent Articles