まくろぐ
更新: / 作成:
Linux に付属されている rsync コマンドを使用すると、2つのディレクトリの内容(ファイル)を効率よく同期させることができます。SSH 経由でのリモートホストへのコピーにも対応しています。

(Windows の場合は、WinSCP をコマンドラインで利用すると同じようなことを実現できます)。

rsync でディレクトリごとコピーする

rsync コマンドを使って、src ディレクトリの内容を dst ディレクトリにコピーするには下記のように実行します。

例: src ディレクトリを dst ディレクトリにコピー
$ rsync -av src/ dst    # src ディレクトリの「中身」を dst ディレクトリ内へコピー
$ rsync -av src dst     # src ディレクトリを dst ディレクトリ内へコピー

-a オプションは、パーミッションやタイムスタンプなどの情報を維持しつつ、ディレクトリを再帰的にコピーする指定をまとめて行うための archive オプションです。 -v オプションは転送情報などを出力する verbose オプションです。

上記例のように、ソースディレクトリの 最後にスラッシュをつけるかつけないかで意味が変わってくる ので注意してください。 2番目のように実行すると、結果として ./dst/src というディレクトリが作成されることになります。

コピー元にないファイルを削除する (–delete)

rsync コマンドはデフォルトでは、コピー先ディレクトリのファイルを削除することはありません。 コピー元 (src) に存在しないファイルを、コピー先 (dst) から削除したいときは、明示的に --delete オプションを付けて実行します。 つまり、2つのディレクトリを同じ内容にしたい(同期したい)のであれば、--delete オプションを付けて実行する必要があります。

例: src の内容を dst に同期させる(src に存在しないファイルは dst から削除する)
$ rsync -av --delete src/ dst

指定した拡張子のファイルだけコピーする (–include)

特定の種類のファイル(png ファイルなど)だけをコピーしたいときは、--include オプションと --exclude を組み合わせて以下のような感じで指定します。

例: src 内の *.png を dst 以下にコピー
$ rsync -av --include='*.png' --include='*/' --exclude='*' src/ dst

この指定方法は少しわかりにくいので、実際にファイルコピーする前に、-n (--dry-run) オプションを付けて実行して、どのようなファイルがコピーされるのかを確認するとよいです。

rsync でリモートホストへディレクトリをコピーする

rsync コマンドは、リモートホストへのファイルコピーにも対応しています(デフォルトで SSH によるファイルコピーが行われます)。 リモートへのファイルコピーを指示したいときは、ターゲットディレクトリの部分を user@hostname:directory というフォーマットで指定します。 ディレクトリ名の部分を省略すると、指定したユーザ (user) のホームディレクトリがコピー先ディレクトリとして使用されます(この場合も、コロン : は省略できません)。

例: リモートホストのホームディレクトリにコピーする
$ rsync -rv --delete src user@example.com:

上記のようにすると、ローカルディレクトリ (src) の中のファイルが、リモートホスト (example.com) のユーザ (user) のホームディレクトリにコピーされます。 末尾のコロン (:) を忘れないように注意してください。 これを忘れると、ローカルに user@example.com という名前のディレクトリができてしまいます。

例: リモートホストのコピー先ディレクトリを指定してコピーする
$ rsync -rv --delete src/ user@example.com:dst

上記のようにすると、ローカルの src ディレクトリの中身が、リモートの dst ディレクトリにコピーされます。 src の後ろにバックスラッシュ (/) を忘れないように注意してください。 これを忘れると、リモートの dst ディレクトリの下に src ディレクトリができてしまいます。

例: 複数のディレクトリをまとめてコピーする
$ rsync -rv --delete src1 src2 src3 user@example.com:dst

上記のようにすると、ローカルの src1src2src3 ディレクトリを、リモートの ~/dst ディレクトリへコピーします。 コピー元のディレクトリ名の末尾にスラッシュ (/) を付けずに実行しているので、リモートの ~/dst ディレクトリ内に src1src2src3 ディレクトリがそれぞれ作成されます(ディレクトリ内のファイルがコピーされるのではなく、ディレクトリごとコピーされる)。

rsync で SSH 鍵を使ってリモートホストに接続する

リモートホスト側の ~/.ssh/authorized_keys に、ローカルホストの SSH 公開鍵を登録しておけば、rsync コマンドでも SSH 鍵による公開鍵認証方式で接続できるようになります。

rsync コマンドの実行方法は、パスワード認証の場合と変わりませんが、代わりに SSH 秘密鍵のパスワード入力プロンプトが表示されます。 秘密鍵にパスワードを設定していない場合は、パスワードの入力なしで rsync が実行されます。

$ rsync -rv --delete src/ user@example.com:dst
Enter passphrase for key '/Users/maku/.ssh/id_rsa': ********

使用する SSH 鍵(秘密鍵)を指定したいときは、次のように -e オプションを使います。

$ rsync -e 'ssh -i ~/.ssh/id_rsa_xxx' -rv --delete src/ user@example.com:dst

シンボリックリンク先の実体をコピーする(-L オプション)

例えば、次のように他のディレクトリへのシンボリックリンクを含む ~/src 以下のファイル群を ~/dst 以下に同期させたいとします。

~/src
  +-- sample.txt
  +-- data/ (~/real-data ディレクトリへのシンボリックリンク)

~/src/data というシンボリックリンクは、例えば ln -s ~/real-data ~/src/data のように作成したもので、実体となる ~/real-data ディレクトリの内容は次のような内容になっています。

~/real-data
   +-- images/
         +-- a.png
         +-- b.png
         +-- c.png

このような構成で ~/src ディレクトリ以下の内容を ~/dst ディレクトリ以下にシンクしてみます(src 自身をコピーしないために src/ のように末尾にスラッシュを忘れずに)。

$ rsync -a ~/src/ ~/dst

すると、デフォルトでは、~/dst の下にシンボリックリンクファイル (data) がそのままコピーされます。

$ ls -Fl ~/src
...省略... data@ -> /Users/maku/real-data
...省略... sample.txt

そうではなくて、リンク先のファイル群の実体をコピーしたいときは、rsync-L (--copy-links) オプション (transform symlink into referent file/dir) を指定します。

$ rsync -aL ~/src/ ~/dst

これで、~/dst/data はシンボリックリンクではなく、~/real-data 以下の内容がすべてコピーされたディレクトリになります。

$ ls -Fl ~/dst
...省略... data/  (通常のディレクトリで、a.png などが含まれている)
...省略... sample.txt
まくろぐ
サイトマップまくへのメッセージ