【シェル】rsyncでサーバーへファイルを差分アップロード【macOS】

【シェル】rsyncでサーバーへファイルを差分アップロード【macOS】
【シェル】rsyncでサーバーへファイルを差分アップロード【macOS】

rsync はファイルの同期を差分で行ってくれる大変便利なシェルコマンドだ。サーバー上のファイルも同期が取れるため、これがないと仕事ができないと言っても過言ではない。DreamweaverやFileZilla、FTP、そしてSCPなどで行っていたら正直仕事が捗らない。 昔はそれでアップロード作業をしていたっす😓

rsyncを知ってからは、アップロード作業が格段に楽になったので、まだ使ったことがない方はこれを期に是非ためしてみてはいかがだろうか。rsyncはとても便利なコマンドではあるが、1つ間違えるとファイルを削除しかねないので使い方には十分注意が必要だ。この記事ではそんなことのないよう、rsyncを動かしながら説明していく。

ざわ...ざわ...
ざわ...ざわ...

rsyncをMacにインストールする

Macにはrsyncが最初から入っているが、バージョンが古いので更新しよう。

shell
$ brew install rsync

brewでインストール後、ターミナルを再起動する。

こちらの環境では、$ rsync --version でバージョンを確認すると3.1.3となった。

shell
rsync  version 3.1.3  protocol version 31
Copyright (C) 1996-2018 by Andrew Tridgell, Wayne Davison, and others.
Web site: http://rsync.samba.org/
Capabilities:
    64-bit files, 64-bit inums, 64-bit timestamps, 64-bit long ints,
    socketpairs, hardlinks, symlinks, IPv6, batchfiles, inplace,
    append, ACLs, xattrs, iconv, symtimes, no prealloc, file-flags

rsync comes with ABSOLUTELY NO WARRANTY.  This is free software, and you
are welcome to redistribute it under certain conditions.  See the GNU
General Public Licence for details.

rsyncの基本的な使い方

rsync の使い方は、いたって簡単。次のように、コピー元とコピー先を指定してやればファイルの同期を差分でやってくれる。そして差分ゆえに同期はあまりにも速い。
shell
$ rsync [オプション] コピー元 コピー先

ちなみに、rsyncのオプションには次のものを指定できる。

記号意味
-aarchive mode( コピー元のディレクトリを再帰的にコピー)
-vincrease verbosity (コピーしているファイル名やバイト数などの情報を表示)
-uskip files that are newer on the receiver ( コピー元とコピー先を比較し、追加・更新されたファイル・ディレクトリのみをコピー)
-ndry-run (お試し実行)
--deleteコピー元にないファイルをコピー先で削除してコピー元とコピー先を同期

コピー元の指定の注意点【スラッシュの重要性】

使い方がとても簡単な rsync だが、ファイルの指定にはちょっと気をつけなければならない。

コピー元にスラッシュをつけるかつけないかで、対象とするファイルがだいぶ異なる。

たとえば次の2つを比較して欲しい。

shell
$ rsync -av src dst

まずはコピー元にスラッシュを付けない場合、ファイルのコピーの対象となるファイルは図の青い部分となる。これは src ディレクトリそのものを含むことになる。

しかし、コピー元にスラッシュを付けた場合、どうなるだろうか?

shell
$ rsync -av src/ dst

この場合、図のように src ディレクトリはコピーの対象に含まれず、src以下のファイル群だけがコピーされる。

「どっちもファイルがコピーされるのだから、一緒じゃん?」と思われるかもしれないが、この違いが結構重要。 rsyncの場合、コピー元と先で同じ構成の同期をとることになるので、ここら辺が曖昧だと、うっかりファイルを削除しかねない。

スラッシュ付き指定の場合は、 コピー元/* と同じであると理解すると良いかもしれない。

次は、実際にスラッシュによる振る舞いの違いを見ていこう。

rsyncの動作確認【基本編】

それでは実際に動作確認をしていく。

次のディレクトリ構造を作ってテストしてみた。

home/
├src/
│ │
│ └  new.txt
│
└dst/
  │
  └src/
   │
   └ old.txt

srcディレクトリをdst内のsrcディレクトリへ同期させるのが目標となる。

コピー元、コピー先の両方にスラッシュをつけない場合

shell
$ rsync -av src dst/src
shell
$ ls dst/src
src old.txt

dst/srcの中に新しいsrcが入ってしまった😞

コピー元のみにスラッシュをつけた場合

shell
$ rsync -av src/ dst/src
shell
$ ls dst/src
new.txt old.txt

イメージ通りにnew.txtが追加された!😀

コピー元、コピー先の両方にスラッシュをつけた場合

shell
$ rsync -av src/ dst/src/
shell
$ ls dst/src/
new.txt old.txt

2番と同様の結果だ😀

コピー先のみにスラッシュをつけた場合

shell
$ rsync -av src dst/src/
shell
$ ls dst/src
src old.txt

1番と同様のdst/srcの中に新しいsrcが入ってしまった😞

コピー元にスラッシュをつけず、コピー先のディレクトリ名を省略した場合

shell
$ rsync -av src dst/
shell
$ ls dst/src
new.txt old.txt

これもうまくいった!😀

コピー元にスラッシュをつけ、コピー先のディレクトリ名を省略した場合

shell
$ rsync -av src/ dst/
shell
$ ls dst/
new.txt src

dstディレクトリの階層にファイルが追加されてしまった😞

ここまでのまとめ【正しく同期できた書き方】

ここまでで、正しく同期できた書き方は次の3つである。

shell
$ rsync -av src/ dst/src
$ rsync -av src/ dst/src/
$ rsync -av src dst/

rsyncの動作確認【--deleteオプションを付けた場合】

--deleteはたいへん危険なので、必ずバックアップをとりつつ、テスト環境で何度も試してから使用しよう。

動作確認その1と同じ構造のディレクトリを用意。

今度は、--deleteオプションをつけて、コピー元に存在しないファイルはコピー先でも削除して同期するようにしてみよう。

home/
│
├src/
│ │
│ └  new.txt
└dst/
  │
  └src/
   │
   └ old.txt

rsyncの動作確認その1 でおこなった2・3・5番の3パターンに、—deleteオプションを追加して試してみよう。

shell
$ rsync -av --delete src/ dst/src
$ rsync -av --delete src/ dst/src/
$ rsync -av --delete src dst/

結果はどれも同じでold.txtが削除され、新たにnew.txtが追加され同期される。これなら問題なさそうだ。

shell
$ ls dst/src
new.txt

今度はrsyncの動作確認その1で行なった1番と4番に、—deleteオプションを追加して試してみよう。

shell
$ rsync -av --delete src dst/src
$ rsync -av --delete src dst/src/

1番と4番は dst/src/ の中にさらにsrcを作ってしまったが、old.txtは削除されていない。

shell
$ ls dst/src/        
old.txt src

それでは最後にrsyncの動作確認その1で行なった、6番に—deleteオプションをつけて実行してみる。

shell
$ rsync -av --delete src/ dst/

なんと!、dst内のsrcをまるまる削除してしまった。

残っているのはnew.txtのみである。

shell
$ ls dst
new.txt

srcの中身をdstにまるごと同期したいなら良いかもしれないが。

スラッシュの違いを理解してどこのディレクトリを操作するのかイメージできていないと大変なことになってしまう。コピー元にスラッシュをつけると、そのディレクトリ以下のファイル群が対象となり、スラッシュをつけなければ、ディレクトリごとが対象となる。しつこいかもしれないが、//*の意味になることをお忘れなく。

ところで、rsyncには dry-runのお試し実行がある。-nオプションをつけることで可能だ。これは同期をせずに、もし同期する場合に対象となるファイルを標準出力してくれるもので、大変便利なオプションだ。不安な方は、本番の同期を実行する前に必ず dry-run を試した方が良いだろう。

shell
$ rsync -avn --delete src/ dst/
sending incremental file list
deleting src/old.txt
deleting src/
./
new.txt

以上で rsync の基本的な使い方の説明は終わりとなる。

rsyncの補足

最後に、rsync は次の特徴があることを補足しておく。

  • ファイルやディレクトリの同期を行うことができる
  • 差分アルゴリズムでデータ転送量が最小になるので転送が高速にできる
  • 開発者はAndrew Tridgellなど複数人の共同開発(sambaの作者でもある
  • ローカルはもちろんSSHでリモートでも使える
  • GNU General Public Licence
  • TCPポート番号873を使う
  • 1996年に最初のリリース

関連記事

最後までご覧いただきありがとうございます!

▼ 記事に関するご質問やお仕事のご相談は以下よりお願いいたします。
お問い合わせフォーム

関連記事