rsync
rsync は高速な差分ファイル転送を行うオープンソースのユーティリティです。
インストール
rsync をソースマシンと転送先マシンの両方にインストールする必要があります。
フロントエンド
- Grsync — GTK フロントエンド
- JotaSync — スケジューラ内蔵の rsync 用 Java Swing GUI
- luckyBackup — C++ で書かれた Qt フロントエンド
その他に rsync を使っているツールは以下の通りです: rdiff-backup 、osyncAUR および yarsyncAUR
cp/mv の代わりとして使う
rsync は cp
または mv
コマンドの上位互換として使うことができ、特に大きなファイルのコピーに役立ちます:
$ rsync -P source destination
-P
オプションは --partial --progress
と同じで、一部ずつファイルを転送して、転送中にプログレスバーを表示します。
ディレクトリを再帰的にコピーしたいときは -r --recursive
オプションを使用し、相対パス名を使いたい時は -R
を使います (転送先のフォルダでフォルダ全体の階層を再生成します。)
cp
と同様にローカルにコピーする事に使えるだけでなく、例えば異なるホスト間といった、リモート同士でファイルをコピーする事にも使えます。リモートの場所はホスト-コロンシンタックスを使って指示できます:
$ rsync source host:destination
あるいは
$ rsync host:source destination
ネットワークを利用したファイルのやりとりには SSH をデフォルトで使い、host
は実際のホスト名かもしくは .ssh/config
で定義されたプロファイルやエイリアスで指示できます。
ローカルかリモートでのファイルのやりとりに関わらず、 rsync はまず始めにファイル情報を含むファイルリストを作成します (デフォルトでは、ファイル情報はサイズと最後に修正したタイムスタンプから成ります。) このファイルリストは次にファイルを構築する必要があるか否かの判断に利用されます。それぞれのファイルを構築する際には、それぞれのブロックが長さ S バイトでオーバーラップがなくまた長さ S で分割可能なようなオフセットを持つようにブロックに分けられ、弱いチェックサムと強いチェックサムを生成します。これら情報によって、rsync はファイル全体をやりとりすることなく巨大なファイルを構築することができます。実用的かつ数学的な詳細な説明は、こちらを参照してください: rsync がどのように動作するか、rsync のアルゴリズム
実用的なデフォルトの設定を手早く使いたい場合は、次の様にしてエイリアスを定義できます:
cpr() { rsync --archive -hh --partial --info=stats1,progress2 --modify-window=1 "$@" } mvr() { rsync --archive -hh --partial --info=stats1,progress2 --modify-window=1 --remove-source-files "$@" }
-hh
: 数を読み易いフォーマット (human-readable format) で出力します--info=stats1,progress2
:stats1
は rsync のファイル移行の統計を verbosity level 1 で出力します。progress2
は全やりとりの進捗を出力し、progress1
はファイル毎に進捗を出力します。--modify-window=1
: 2つのファイルのタイムスタンプを比較する際に 1秒以下の違いがあっても同じタイムスタンプとして処理します。--remove-source-files
: 正常にファイルのやりとりができた後に、ソースディレクトリからファイルを削除します。
末尾のスラッシュに関する注意事項
Arch はデフォルトで GNU cp (GNU coreutils の一部) を使用します。 ただし、rsync は BSD cp の規則に従います。これは、末尾にスラッシュ 「/」 が付いたソースディレクトリに特別な処理を与えます。
$ rsync -r source destination
ディレクトリ "destination/source" を "source" の内容で作成するのに対して、
$ rsync -r source/ destination
は "source/" 内のすべてのファイルを "destination" にコピーしてその間にサブディレクトリは置きません。もし次を実行した様になります
$ rsync -r source/. destination
GNU cp は "source" と "source/" を同じように扱うので ("source/." は違います) これらの動作は GNU cp の動作とは異なります。また、シェルによっては、タブを補完するディレクトリ名の末尾にスラッシュを自動的に付加するものもあります。これらの要因のために、 rsync を初めて使う、あるいは時々使うユーザの間では、 rsync の異なる動作を忘れてしまい、コマンドラインの最後にあるスラッシュを忘れてしまうことで、混乱を招いたり、重要なファイルを上書きしたりする傾向があります。
したがって、ラッパースクリプトを使用して、rsync を呼び出す前に末尾のスラッシュを自動的に削除することが賢明です:
#!/bin/bash new_args=() for i in "${@}"; do case "${i}" in /) i="/" ;; */) i="${i%/}" ;; esac new_args+=("${i}") done exec rsync "${new_args[@]}"
このスクリプトをパスの通った場所に置き、シェルの init ファイル内で rsync というエイリアスを付けられます。
バックアップユーティリティとして使う
rsync プロトコルは最後にバックアップされた時点から変更があったファイルだけを転送することができ、簡単にバックアップの為に使う事ができます。この節では、リムーバルメディアへコピーするといった、シンプルな定期的なバックアップスクリプトを紹介します。
自動バックアップ
このサンプルを使うには、スクリプトを /etc/cron.daily
ディレクトリに作成して下さい。cron デーモン をインストールして適切に設定することで毎日実行せせるようになります。
まず、適切なコマンドオプションを含んだスクリプトを作成:
/etc/cron.daily/backup
#!/bin/sh rsync -a --delete --quiet /path/to/backup /location/of/backup
-a
: ファイルをアーカイブする。ファイルの属性も保存 (ただし ACL やハードリンク、ケイパビリティなどの拡張属性は除外)--delete
: バックアップ元で削除されたファイルはバックアップ先でも同じように削除する
ここで、/path/to/backup
はバックアップしたいものに (例えば /home
)、/location/of/backup
はバックアップの保存先に変更します (例えば /media/disk
)
最後に、スクリプトを 実行可能 にします:
SSH を使った自動バックアップ
SSH を使ってリモートホストにバックアップする場合、以下のスクリプトを使用:
/etc/cron.daily/backup
#!/bin/sh rsync -a --delete --quiet -e ssh /path/to/backup remoteuser@remotehost:/location/of/backup
-e ssh
: rsync に SSH を使うことを教えるremoteuser
: ホストremotehost
のユーザー-a
:-rlptgoD
オプションと同義 (recursive, links, perms, times, group, owner, devices)
NetworkManager を使った自動バックアップ
以下のスクリプトはケーブルを接続した時にバックアップを開始します。
まず、適当なコマンドオプションを含んだスクリプトを作成:
/etc/NetworkManager/dispatcher.d/backup
#!/bin/sh if [ x"$2" = "xup" ] ; then rsync --force --ignore-errors -a --delete --bwlimit=2000 --files-from=files.rsync /path/to/backup /location/of/backup fi
-a
:-rlptgoD
オプションと同義 (recursive, links, perms, times, group, owner, devices)--files-from
: ファイルから/path/to/backup
の相対パスを読み込み--bwlimit
: I/O 帯域を制限、単位はキロバイト毎秒
このスクリプトの所有者をルートユーザにして下さい (詳しくは NetworkManager dispatcher を参照)
systemd と inotify を使った自動バックアップ
cron の実装など、スケジュールによって適宜バックアップを実行するのではなく、この方法ではバックアップするファイルに変更があった度にバックアップを実行することが可能です。systemd.path
ユニットは inotify
を使ってファイルシステムを監視し、systemd.service
と一緒に使うことでファイルシステムのイベントに合わせてあらゆるプロセスを開始することができます (この場合は rsync のバックアップ。)
まず、バックアップするファイルを監視する systemd.path
ファイルを作成:
~/.config/systemd/user/backup.path
[Unit] Description=Checks if paths that are currently being backed up have changed [Path] PathChanged=%h/documents PathChanged=%h/music [Install] WantedBy=default.target
そして変更を検出した時に実行される systemd.service
ファイルを作成します。デフォルトで、パスユニット (ここでは backup.path
) と同じ名前の、拡張子が .path
ではなく .service
のサービスファイルが実行されます (ここでは backup.service
)
~/.config/systemd/user/backup.service
[Unit] Description=Backs up files [Service] ExecStart=/usr/bin/rsync %h/./documents %h/./music -CERrltm --delete ubuntu:
これで、通常の systemd サービスのように backup.path
起動/有効化 を実行するだけで、ファイルの変更が監視され、backup.service
が自動的に開始されます。
一週間ごとに差分バックアップ
実行毎の完全なバックアップを作成して、ファイルに変更があったものだけの差分バックアップのコピーを分かれたディレクトリに保持しつつ、一週間ごとに差分バックアップを行う便利な rsync のオプションです。
まず、適当なコマンドオプションを含むスクリプトを作成:
/etc/cron.daily/backup
#!/bin/sh DAY=$(date +%A) if [ -e /location/to/backup/incr/$DAY ] ; then rm -fr /location/to/backup/incr/$DAY fi rsync -a --delete --quiet --inplace --backup --backup-dir=/location/to/backup/incr/$DAY /path/to/backup/ /location/to/backup/full/
--inplace
オプションは --partial
を伴ない、転送先のファイルを所定の場所に更新します。
スナップショットバックアップ
同じアイデアを使ってファイルのスナップショットのツリーを作ることができます。言い換えれば、ファイルのコピーが含まれる日付順のディレクトリです。コピーはハードリンクで作られ、変更があったファイルだけが場所を取ります。これは Apple の TimeMachine で使われているアイデアです。
次の基本的なスクリプトは簡単な実装であり、変更がないファイルへハードリンクさせる --link-dest
オプションを使って素早くインクリメンタルスナップショットを生成します:
/usr/local/bin/snapbackup.sh
#!/bin/sh # Basic snapshot-style rsync backup script # Config OPT="-aPh" LINK="--link-dest=/snapshots/username/last/" SRC="/home/username/files/" SNAP="/snapshots/username/" LAST="/snapshots/username/last" date=`date "+%Y-%b-%d:_%T"` # Run rsync to create snapshot rsync $OPT $LINK $SRC ${SNAP}$date # Remove symlink to previous snapshot rm -f $LAST # Create new symlink to latest snapshot for the next backup to hardlink ln -s ${SNAP}$date $LAST
--link-dest
のために既にターゲットに存在しているフルバックアップへのシンボリックリンクが必須です。最新のスナップショットが削除された場合、最新のスナップショットへのシンボリックリンクを再生成する必要があります。--link-dest
が動作しているシンボリックリンクを見付けられなかった場合、rsync は差分だけでなくソースファイルの全てをコピーします。
より洗練されたバージョンは、$SNAP/lates
の最新のフルバックアップと最後のバックアップからの数回分の変更を保持します。現在のフルバックアップのスナップショット $SNAP/$DATETAG
を、変更がないファイルへハードリンクさせるために cp -al
を使って生成します:
/usr/local/bin/rsnapshot.sh
#!/bin/sh ## my own rsync-based snapshot-style backup procedure ## (cc) marcio rps AT gmail.com # config vars SRC="/home/username/files/" #dont forget trailing slash! SNAP="/snapshots/username" OPTS="-rltgoi --delay-updates --delete --chmod=a-w" MINCHANGES=20 # run this process with real low priority ionice -c 3 -p $$ renice +12 -p $$ # sync rsync $OPTS $SRC $SNAP/latest >> $SNAP/rsync.log # check if enough has changed and if so # make a hardlinked copy named as the date COUNT=$( wc -l $SNAP/rsync.log|cut -d" " -f1 ) if [ $COUNT -gt $MINCHANGES ] ; then DATETAG=$(date +%Y-%m-%d) if [ ! -e $SNAP/$DATETAG ] ; then cp -al $SNAP/latest $SNAP/$DATETAG chmod u+w $SNAP/$DATETAG mv $SNAP/rsync.log $SNAP/$DATETAG chmod u-w $SNAP/$DATETAG fi fi
このスクリプトを systemd のタイマー ユニットから実行することで、よりシンプルにできます。
システムのフルバックアップ
このセクションでは、 rsync を使用して、選択したいくつかのディレクトリを除く /
ツリー全体のコピーを転送する方法について説明します。 このアプローチは、 dd
を使用した ディスクのクローン よりも優れていると考えられます。これは、異なるサイズ、パーティションテーブル、およびファイルシステムを使用できるためであり、 cp-a
を使用したコピーよりも優れているためです。これにより、ファイルのアクセス許可、属性、 アクセス制御リスト および 拡張属性 をより細かく制御できるようになります。
rsync はシステムの実行中でも機能しますが、転送中に変更されたファイルは転送される場合とされない場合があり、転送されたファイルを使用する一部のプログラムの未定義の動作を引き起こす可能性があります。
このアプローチは、既存の環境を新しい HDD または SSD に移行する場合に適しています。
rootとして次のコマンドを実行して下さい。root権限で実行することで rsync がすべてのシステムファイルにアクセスし、所有権を保持できます:
# rsync -aAXHv --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} / /path/to/backup
-aAX
のオプションセットを使用することにより、ファイルはアーカイブモードで転送され、シンボリックリンク、デバイス、アクセス許可、所有権、変更時間、 ACL、 および拡張属性が保持されます。 ターゲット ファイルシステム がこの機能をサポートしていると仮定します。 オプション -H
はハードリンクを保持しますが、より多くのメモリを使用します。
--exclude
オプションを指定すると、指定したパターンに一致するファイルが除外されます。ディレクトリ /dev
、 /proc
、 /sys
、 /tmp
、 /run
は上記のコマンドに含まれますが、これらのディレクトリの 内容 は除外されます。これは、起動時にはディレクトリが作成されますが、ディレクトリ自体は作成されないためです。/lost+found
はファイルシステム固有です。上記のコマンドは、 bashおよび zsh シェルの両方で使用できるブレース展開に依存します。別の シェル を使用する場合は、 --exclude
パターンを手動で繰り返す必要があります。除外パターンを引用符で囲むと、 シェル による展開が回避されます。これは、たとえば SSH のバックアップ時に必要です。除外パスの最後に *
を指定すると、ディレクトリ自体がまだ存在しない場合でも作成されます。
追加の rsync オプションを含めるか、次のようないくつかを削除することをお勧めします。 完全なリストについては、 rsync(1) を参照してください。
- メモリが非常に少ないシステムで実行している場合は、
-H
オプションを削除することを検討してください。ただし、最近のほとんどのマシンでは問題ありません。使用するソフトウェアによっては、ファイルシステムに多くのハードリンクが存在する可能性があります(たとえば、 Flatpak を使用している場合)。多くのハードリンクは/usr/
ディレクトリの下にあります。 - これを同じバックアップディレクトリで複数回実行している場合は、rsync の
--delete
オプションを追加することをお勧めします。この場合、ソースパスが/*
で終わっていないことを確認してください。そうでない場合、このオプションはソースディレクトリのサブディレクトリ内のファイルにのみ影響しますが、存在するファイルには影響しません。 - 仮想ディスク、 Docker イメージなどのスパースファイルを使用する場合は、
-S
オプションを追加する必要があります。 --numeric-ids
オプションは、ユーザー名とグループ名のマッピングを無効にします。代わりに、数値のグループ ID とユーザー ID が転送されます。これは、 SSH を介してバックアップする場合、またはライブシステムを使用して別のシステムディスクをバックアップする場合に役立ちます。-v
の代わりに-info=progress2
オプションを選択すると、転送されるファイルのリストではなく、全体的な進行状況情報と転送速度が表示されます。- 再帰時にファイルシステムの境界を越えないようにするには、オプション
-x
/--one-file-system
を追加します。これにより、階層内のマウントポイントをバックアップできなくなります。
バックアップを復元する
バックアップを復元する場合は、実行されたのと同じ rsync コマンドを使用しますが、ソースと宛先を逆にします。
フィルター規則の高度な使用法
包含ルールと除外ルールを個別に指定する代わりに、rsync は単一のフィルター ファイルからこれらすべてを読み取ることができます。次に、rsync はルールを上から順に処理します。最初に一致したルールが優先されます。
backup.filter
# Exclude patterns - .thumbnails/*** - node_modules/*** - venv/*** # Include patterns + /Documents/*** + /Books/*** + /Music/*** # Exclude everything else - /**
***
は、フォルダーとそのすべてのコンテンツを再帰的に照合する特別な rsync パターンです。
詳細については、rsync(1) § PATTERN MATCHING RULES および rsync(1) § FILTER RULES IN DEPTH を確認してください。
次に、以下のように rsync を実行します。
$ rsync -aAXHv --filter="merge backup.filter" $SRC $DEST
キーワードは --filter "merge ..."
パラメータで、フィルタファイルを受け取り、同期された各ファイルのルールを順番に解析します。
パスのリストからコピー
#フィルター規則の高度な使用法 方法の代わりに、--files-from
オプションを使用することもできます。これは、各エントリが改行で区切られたディレクトリまたはファイルパスのリストを含むテキストファイルから入力を受け取ることができます、ユーザーが再帰的なディレクトリのコピーを望む場合は、-a
がすでに含まれている場合でも、このオプションに -r
フラグを手動で指定する必要があることに注意してください。
たとえば、ディレクトリのリストとすべての再帰ディレクトリは、次のようにアーカイブできます:
$ rsync -aAXHvr --files-from="dir_list.txt" $SRC $DEST
ファイルシステムのクローニング
rsync は、ファイルシステムのメタデータを含む可能な限り多くの情報を保持しながら、ファイルシステム内のすべてのデータのコピーを実行する方法を提供します。 これは、ソースファイルシステムと宛先ファイルシステムが同じタイプである必要がないファイルシステムレベルでのデータ複製の手順です。 バックアップ、ファイルシステムの移行、またはデータ復旧に使用できます。
rsync の "アーカイブ" モードは、アクセス制御リスト、拡張属性、スパースファイルプロパティなどの特別なファイルシステムメタデータはバックアップされません。 ファイルシステムレベルでのクローンを成功させるには、いくつかのオプションを追加する必要があります。
rsync -qaHAXS SOURCE_DIR DESTINATION_DIR
それらの意味は (manpageから):
--hard-links, -H ハードリンクを保持する --acls, -A ACLを保持する(--perms を意味します) --xattrs, -X 拡張属性を保持する --sparse, -S null シーケンスを疎らなブロックに変換する
さらに、コピーから除外するツリーの下に他のファイルシステムがマウントされている場合は、 -x
を使用します。
生成されたコピーは、 diff
の再帰オプションを使用して、ファイルシステムレベルで簡単に再読み取りおよびチェックできます(たとえば、データ回復の試行後)
生成されたコピーは、diff
の再帰オプションを使用して、ファイルシステムレベルで単純に再読み取りおよびチェックできます (たとえば、データ リカバリの試行後)
diff -r SOURCE_DIR DESTINATION_DIR
rsync を使用し、 新しいハードウェアに移行する で説明されているように fstab と ブートローダー を更新することで、ファイルシステムの移行を成功させることができます。 これは基本的に、ルートファイルシステムを別のルートファイルシステムに変換する時にも適しています。
デーモンとして
rsync は、ポート 873
で待機しているサーバー上でデーモンとして実行できます。
テンプレート /etc/rsyncd.conf
を編集して共有を設定し、rsyncd.service
を スタート します。
クライアントからの使用法 (例:サーバーのコンテンツリスト):
$ rsync rsync://server/share
クライアントからサーバーにファイルを転送する:
$ rsync local-file rsync://server/share/
ファイアウォール で TCP ポート 873
を開き、ユーザー認証を使用することを検討してください。
設定例
ファイルのリストから共有する
/etc/rsyncd.conf
... # Needed when crossing filesystem boundaries. #use chroot = no read only = yes ... [sync] path = / # List of files to copy. include from = /backup.list # Exclude the rest. exclude = *
ファイルリスト内では、ワイルドカード ***
が使用されている場合を除き、すべての 中間パス が必要です:
/backup.list
/etc/ /etc/conf.d/ /etc/conf.d/hwclock /etc/fonts/***
参照
- その他の使用例は、こちらで検索できます。 Community Contributions , General Programming フォーラム
- Howto – local and remote snapshot backup using rsync with hard links ハードリンクによるファイル重複排除、MD5 完全性署名、"chattr" 保護、フィルタールール、ディスククォータ、指数分布による保持ポリシー (古いバックアップより新しいバックアップを保存しながらローテーションする) を含みます。
- Using SSH keys/identity files with rsync