rsync

提供: ArchWiki
2023年2月8日 (水) 05:05時点におけるKgx (トーク | 投稿記録)による版 (→‎フロントエンド: 同期)
ナビゲーションに移動 検索に移動

関連記事

rsync は高速な差分ファイル転送を行うオープンソースのユーティリティです。

インストール

公式リポジトリから rsyncインストールしてください。

rsync をソースマシンと転送先マシンの両方にインストールする必要があります。

フロントエンド

  • Grsync — GTK フロントエンド
http://www.opbyte.it/grsync/ || grsync
  • JotaSync — ​スケジューラ内蔵の rsync 用 Java Swing GUI
https://trixon.se/projects/jotasync/ || jotasyncAUR
  • luckyBackup — ​C++ で書かれた Qt フロントエンド
http://luckybackup.sourceforge.net/index.html || luckybackupAUR

​その他に rsync を使っているツールは以下の通りです: rdiff-backuposyncAUR

cp/mv の代わりとして使う

ノート: cp/mv の代わりに rsync を使う事は異なるファイルシステム間では効果的ですが、同じファイルシステム上でコピーや移動する場合効果はありません。詳しくは [1] を参照してください。

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: 正常にファイルのやりとりができた後に、ソースディレクトリからファイルを削除します。
ノート: ここでの「チェックサム」は --checksum オプションでの振る舞いとは互換性がありません。--checksum オプションはファイルの転送前に使用されるファイルスキップヒューリスティックに影響します。--checksum とは無関係に、「チェックサム」は、rsync がファイルを転送する方法であるブロックベースのファイル構築で常に使用されます。

​末尾のスラッシュに関する注意事項

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)
ノート: Rsync は、インクリメンタルバックアップでもってソース元のマシンでの状態と合うようにターゲットマシンのファイルを更新しようとします。つまり、SSH を越えてルートユーザがオーナーであるファイルをバックアップする場合 (あるいは -a などによってパーミッションやオーナシップを保とうとする場合) はターゲットマシンのルートアクセスが必要になります。自動的にこれを実行しようとする場合、SSH デーモンに パスワード無しの公開鍵 を使ってルートユーザにログインすることを許可するように設定して、rsync をルート権限で実行することが良いでしょう。

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 を使った自動バックアップ

ノート:
  • inotify と systemd の制限により (この質問と答え を参照) 再帰的なファイルシステムの監視は不可能です。ディレクトリとその中身を監視することはできますが、サブディレクトリにまで再帰的に実行してその中身を監視することはされません。監視するディレクトリは全て明示的に指定する必要があります (ディレクトリが既に指定した監視ディレクトリの下にあっても記述する必要があります。)
  • このセットアップは systemd/ユーザー インスタンスをベースにしています。

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)

ノート: rsync コマンドを複数実行する必要がある場合は、Type=oneshot を使って下さい。実行する rsync ごとに、複数の ExecStart= パラメータを指定することができます。もしくは、cron スクリプトなど、バックアップ作業を全て実行するスクリプトを書いても良いでしょう。
~/.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 のバックアップ時に必要です。​除外パスの最後に * を指定すると、ディレクトリ自体がまだ存在しない場合でも作成されます。

ノート:
  • /mnt または /media 以外の場所でシステムをバックアップする場合は、無限ループを回避するために、除外パターンのリストにシステムを追加することを忘れないでください。
  • システムにバインドマウントがある場合は、それらも除外して、バインドマウントされたコンテンツが1回だけコピーされるようにする必要があります。
  • スワップファイル を使用している場合は、必ず除外してください。
  • /home/ ディレクトリをバックアップするかどうかを検討してください。 データが含まれている場合は、システムよりもかなり大きくなる可能性があります。 それ以外の場合は、 /home/*/.thumbnails/*, /home/*/.cache/mozilla/*, /home/*/.cache/chromium/*, と /home/*/.local/share/Trash/* などの重要でないサブディレクトリを除外することを検討してください。 /home/*/.local/share/Trash/* は、システムにインストールされているソフトウェアによって異なります。
  • GVFS がインストールされている場合、 rsync エラーを防ぐために、 /home/*/.gvfs を除外する必要があります。
  • Dhcpcd ≥9.0.0 がインストールされている場合は、 /var/lib/dhcpcd/* ディレクトリを除外します。これは、いくつかのシステムディレクトリをサブディレクトリとしてマウントするためです。

追加の 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 ..." パラメータで、フィルタファイルを受け取り、同期された各ファイルのルールを順番に解析します。

ファイルシステムのクローニング

rsync は、ファイルシステムのメタデータを含む可能な限り多くの情報を保持しながら、ファイルシステム内のすべてのデータのコピーを実行する方法を提供します。 これは、ソースファイルシステムと宛先ファイルシステムが同じタイプである必要がないファイルシステムレベルでのデータ複製の手順です。 バックアップ、ファイルシステムの移行、またはデータ復旧に使用できます。

rsync の "アーカイブ" モードは、アクセス制御リスト、拡張属性、スパースファイルプロパティなどの特別なファイルシステムメタデータはバックアップされません。 ファイルシステムレベルでのクローンを成功させるには、いくつかのオプションを追加する必要があります。

rsync -qaHAXS SOURCE_DIR DESTINATION_DIR

それらの意味は (manpageから):

--hard-links, -H         ハードリンクを保持する
--acls, -A               ACLを保持する(--perms を意味します)
--xattrs, -X             拡張属性を保持する
--sparse, -S             null シーケンスを疎らなブロックに変換する

さらに、コピーから除外するツリーの下に他のファイルシステムがマウントされている場合は、 -x を使用します。 生成されたコピーは、 diff の再帰オプションを使用して、ファイルシステムレベルで簡単に再読み取りおよびチェックできます(たとえば、データ回復の試行後)

ノート: rsync を使用して Arch インストールを新しいドライブに移行する場合は、​末尾のスラッシュに関する注意事項 で述べたように、SOURCE_DIR の最後に末尾のスラッシュを含めることを忘れないでください。

生成されたコピーは、diff の再帰オプションを使用して、ファイルシステムレベルで単純に再読み取りおよびチェックできます (たとえば、データ リカバリの試行後)

diff -r SOURCE_DIR DESTINATION_DIR

rsync を使用し、 新しいハードウェアに移行する で説明されているように fstabブートローダー を更新することで、ファイルシステムの移行を成功させることができます。 これは基本的に、ルートファイルシステムを別のルートファイルシステムに変換する時にも適しています。

rsync デーモン

rsync は、ポート 873 で待機しているサーバー上でデーモンとして実行できます。

​テンプレート /etc/rsyncd.conf を編集して共有を構成し、 rsyncd.serviceスタート します。

ノート: rsync 3.2.0-1 の時点で、パッケージはアップストリーム systemd ユニットファイル rsyncd.servicersyncd@.service を採用しました。 ProtectHome の変更についてコメントがあり、 [Service] セクションのセキュリティ機能 ProtectSystem=full は引き続きアクティブです。 これにより、 /boot//etc/、 および /usr/ ディレクトリが読み取り専用になります。 rsyncd 書き込みシステムディレクトリが必要な場合は、ユニットを 編集 して、オーバーライドするスニペットの [Service] セクションで ProtectSystem=off を設定できます。

クライアントからの使用

例:サーバーコンテンツの一覧表示:

$ rsync rsync://server/share

クライアントからサーバーにファイルを転送する:

$ rsync local-file rsync://server/share/

ポート 873 とユーザー認証を開くための iptables を検討してください。

ノート: ユーザー認証を含むすべての転送データは暗号化されていません。

設定例

ファイルのリストから共有する

/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/***

参照