rsync入門|差分だけを速くコピーする基本オプション

rsync入門|差分だけを速くコピーする基本オプション

サーバーのファイルを手元へ持ってくるとき、私はずっと cp と scp だけで済ませていました。

ところが同じディレクトリを何度も往復させるようになると、毎回まるごと転送する待ち時間がばかになりません。

そこで rsync に乗り換えたところ、2回目以降の実行が体感で一瞬になりました。

rsync は「前回との差分だけを送る」ことに特化したコピーコマンドです。

この記事では、私が普段実際に打っている範囲のオプションだけを、実行結果つきで並べていきます。

検証環境は Ubuntu 22.04.5・rsync 3.2.7(protocol 31)でした。

まずは -av だけ覚える

基本形は rsync に続けてオプション、コピー元、コピー先を並べるだけ。

最初に覚えるオプションは -a と -v の2つで足ります。

-a は archive の頭文字で、サブディレクトリ・パーミッション・タイムスタンプをまとめて保ったまま運ぶ指定。

-v は verbose、つまり何を転送したかを画面に出す指定です。

$ rsync -av src/ dst/
sending incremental file list
a.txt
b.log
sub/
sub/c.txt

sent 352 bytes  received 85 bytes  874.00 bytes/sec
total size is 20  speedup is 0.05

4つのエントリが転送され、サブディレクトリもそのまま再現されました。

おもしろいのは、続けてもう一度まったく同じコマンドを打ったとき。

$ rsync -av src/ dst/
sending incremental file list

sent 188 bytes  received 13 bytes  402.00 bytes/sec
total size is 20  speedup is 0.10

ファイル名が1つも並びません。

中身が変わっていないファイルは、まるごと読み飛ばされているわけです。

では a.txt だけ書き換えてから、三度目を実行してみます。

$ printf 'alpha-updated\n' > src/a.txt
$ rsync -av src/ dst/
sending incremental file list
a.txt

sent 249 bytes  received 36 bytes  570.00 bytes/sec
total size is 28  speedup is 0.10

変わった1ファイルだけが選ばれて流れました。

この挙動こそが、cp との決定的な違いになります。

いちばんの事故は、末尾スラッシュ

rsync で最初につまずくのは、オプションではなくコピー元の末尾スラッシュでした。

同じ src を指しているつもりでも、スラッシュの有無で結果が変わります。

$ rsync -a src/ d1/   # src の「中身」を d1 直下へ
$ rsync -a src  d2/   # src「ごと」d2 の下へ

$ find d1 | sort
d1
d1/a.txt
d1/b.log
d1/sub
d1/sub/c.txt

$ find d2 | sort
d2
d2/src
d2/src/a.txt
d2/src/b.log
d2/src/sub
d2/src/sub/c.txt

d2 のほうだけ、src という階層が1段よけいに増えました。

スラッシュを1つ落としただけで、コピー先の構造が変わってしまう

迷ったときは -n、つまり –dry-run を足して、転送されるはずのファイル名だけ先に眺めます。

$ printf 'delta\n' > src/d.txt
$ rsync -avn src/ dst/
sending incremental file list
./
d.txt

sent 224 bytes  received 23 bytes  494.00 bytes/sec
total size is 34  speedup is 0.14 (DRY RUN)

末尾に (DRY RUN) と出ているとおり、この実行ではコピー先に1バイトも書かれていません。

私は初見のディレクトリを相手にするとき、必ずこの -n 付きを一度はさむようにしています。

–delete と –exclude は意味を掴んでから

コピー先をコピー元の鏡写しにしたいなら –delete の出番です。

$ rm src/b.log
$ rsync -av --delete src/ dst/
sending incremental file list
deleting b.log
./
d.txt

sent 254 bytes  received 55 bytes  618.00 bytes/sec
total size is 28  speedup is 0.09

コピー元から消したファイルが、コピー先でも削除されました。

–delete は取り消しのきかない削除を伴うので、–dry-run で確認してから本番に回す

逆に、そもそも送りたくないものは –exclude で外しておきます。

$ rsync -av --exclude='*.log' src/ dst2/
sending incremental file list
created directory dst2
./
a.txt
d.txt
sub/
sub/c.txt

拡張子 .log のファイルだけが候補から外れました。

ログやキャッシュを巻き込まずに済むので、実務ではこちらのほうが出番が多い印象。

リモートを相手にするときの形

コピー元かコピー先のどちらかを user@host:/path と書けば、そのまま ssh 越しの転送になります。

ローカル同士との違いは、この1点だけ。

鍵の作り方や ~/.ssh/config での短縮は、SSH 側の記事にまとめています。

SSH入門|安全にリモート接続する鍵認証の基本
# リモートのログ置き場を手元へ取り寄せる
rsync -avz --progress user@example.com:/var/log/myapp/ ./logs/

# 途中で切れても、同じコマンドを打ち直せば続きから
rsync -avzP user@example.com:/var/log/myapp/ ./logs/

-z は転送時の圧縮、–progress は進捗表示の指定です。

-P はその –progress と –partial をまとめたもので、途中まで届いたファイルを捨てずに残す働きをします。

だから回線が切れても、同じコマンドをもう一度叩けば残りだけが流れる。

なお上のリモート例は書式を示したもので、手元の検証はローカル同士のディレクトリで行いました。

最後に

rsync は cp の置き換えというより、2回目以降が劇的に速くなるコピーだと捉えると腑に落ちます。

覚える順番は -av、次に –dry-run、最後に –delete と –exclude の3段でじゅうぶんでした。

末尾スラッシュだけは、今でも打つ手を一度止めて確かめるのが習慣です。

まるごと固めて持ち出したいときは、差分コピーではなく tar の出番。

tarコマンド入門|ファイルをまとめる・圧縮する・展開する

詳しい仕様はrsync 公式サイトと man rsync が一次情報になります。

以上です。

コメントを残す

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

CAPTCHA