1. 概要

多くの場合、ファイルまたはディレクトリをローカルマシン上の別の場所、またはローカルマシンとリモートマシンの間でバックアップする必要があります。 コピーアンドペーストで手動で行うこともできますが、これには時間がかかり、エラーが発生しやすくなります。または、コマンドやプログラムを利用して行うこともできます。

このチュートリアルでは、1台のマシンでディレクトリを両方向に同期するためのいくつかのコマンドまたはプログラムをテストし、結果を比較します。

64ビットrsync 3.1.3、64ビット Unixn 2.51.4、Debian用OCaml 4.05.0バイナリ、 Zaloha2 、および FreeFileSync GNU bash5.0.3を使用する64ビットDebian10.10(Buster)で実行されるLinux用の11.16バイナリ。

2. rsyncコマンドの使用

2.1. インストール

rsync は、Unixライクなオペレーティングシステムでよく見られます。 これはGNUGPLの下でのオープンソースプロジェクトであり、そのソースコードまたはバイナリはそのホームページからダウンロードできます。

2.2. 使用法

rsync は一方向で動作するため、ディレクトリを両方向に同期するには2回実行する必要があります

やってみましょう。 まず、ソースディレクトリとターゲットディレクトリの構造を見てみましょう。

$ tree
.
├── source
│   ├── file01.bin
│   ├── file02.bin
│   └── file03.bin
└── target
    ├── file0A.bin
    ├── file0B.bin
    └── file0C.bin

2 directories, 6 files

それでは、ソースからターゲットに同期しましょう。

$ rsync -Pcauv source/ target/
sending incremental file list
./
file01.bin
              0 100%    0.00kB/s    0:00:00 (xfr#1, to-chk=2/4)
file02.bin
              0 100%    0.00kB/s    0:00:00 (xfr#2, to-chk=1/4)
file03.bin
              0 100%    0.00kB/s    0:00:00 (xfr#3, to-chk=0/4)

sent 297 bytes  received 76 bytes  746.00 bytes/sec
total size is 0  speedup is 0.00

そして、中間結果を確認してください。

$ tree
.
├── source
│   ├── file01.bin
│   ├── file02.bin
│   └── file03.bin
└── target
    ├── file01.bin
    ├── file02.bin
    ├── file03.bin
    ├── file0A.bin
    ├── file0B.bin
    └── file0C.bin

2 directories, 9 files

次に、ターゲットからソースに同期します。

$ rsync -Pcauv target/ source/
sending incremental file list
file0A.bin
              0 100%    0.00kB/s    0:00:00 (xfr#1, to-chk=2/7)
file0B.bin
              0 100%    0.00kB/s    0:00:00 (xfr#2, to-chk=1/7)
file0C.bin
              0 100%    0.00kB/s    0:00:00 (xfr#3, to-chk=0/7)

sent 401 bytes  received 73 bytes  948.00 bytes/sec
total size is 0  speedup is 0.00

それでは、最終結果を確認しましょう。

$ tree
.
├── source
│   ├── file01.bin
│   ├── file02.bin
│   ├── file03.bin
│   ├── file0A.bin
│   ├── file0B.bin
│   └── file0C.bin
└── target
    ├── file01.bin
    ├── file02.bin
    ├── file03.bin
    ├── file0A.bin
    ├── file0B.bin
    └── file0C.bin

2 directories, 12 files

使用するオプションを確認しましょう。

  • -P :個々のファイルではなく転送全体の統計を表示します
  • -c :変更された時間とサイズではなく、チェックサムに基づいてオブジェクトをスキップします
  • -a :アーカイブモードを有効にします。次のようになります。
    • -r :ディレクトリに再帰します
    • -l :シンボリックリンクをシンボリックリンクとしてコピー
    • -p :権限を保持します
    • -t :変更時間を保持
    • -g :グループを保持
    • -o :所有者を保持
    • -D :デバイスファイルと特殊ファイルを保持します
  • -u :ターゲット上の新しいファイルをスキップします
  • -v :実行されていることの詳細情報を表示します

データの損失を防ぐために、-nオプションを使用してドライランを実行することもできます。これにより、変更を加えずに同期がシミュレートされます

$ rsync -Pcauvn source/ target/
sending incremental file list
./
file01.bin
file02.bin
file03.bin

sent 189 bytes  received 28 bytes  434.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)

3. ユニゾンプログラムの使用

3.1. インストール

ユニゾンのソースコードまたはバイナリダウンロード情報は、そのホームページで入手できます。このホームページでは、執筆時点でこのGitHubリポジトリを指しています。

64ビットのUnison2.51.4とOCaml4.05.0バイナリを使用しています。これにより、次のパッケージが提供されます。

$ tree
.
├── bin
│   ├── unison
│   ├── unison-fsmonitor
│   └── unison-gtk2
├── LICENSE
└── README.md

1 directory, 5 files

3.2. 使用法

unison-gtk 実行可能ファイルを実行することにより、GUIバージョンのUnisonを使用できます。 この記事では、unison実行可能ファイルであるテキストベースのUnisonを使用します。

sourceおよびtargetディレクトリのディレクトリ構造を見てみましょう。

$ tree
.
├── source
│   ├── file01.bin
│   ├── file02.bin
│   └── file03.bin
└── target
    ├── file0A.bin
    ├── file0B.bin
    └── file0C.bin

2 directories, 6 files

最初に同期を行うと、次のインタラクティブなプロンプトが表示されます。

$ ./unison ~/source/ ~/target/
Unison 2.51.4 (ocaml 4.05.0): Contacting server...
Looking for changes
Warning: No archive files were found for these roots, whose canonical names are:
	~/source
	~/target
This can happen either because this is the first time you have synchronized these roots, or because you have upgraded Unison to a new version with a different archive format.  
...
Donations to the Unison project are gratefully accepted: http://www.cis.upenn.edu/~bcpierce/unison

Press return to continue.[<spc>] 

Enter を押して続行するか、qを押して終了します。 Enter を押すと、実行する変更ごとに確認を求められます。

fまたはEnterを押して、それぞれの変更を確認します。 押すことができます >> また < 変更を強制的に左から右、または右から左に伝播するか、を押します / ファイルをスキップして、両方のオブジェクトをそのままにします。

リストの最後に到達すると、ユニゾンは変更を続行するかどうかをもう一度尋ねます。 y を押して続行するか、qを押して終了します。

Unisonが入力を要求するたびに、を押して、考えられるすべての応答とその意味を一覧表示できます。

Reconciling changes

source         target             
file     ---->            file01.bin  [f] f
file     ---->            file02.bin  [f] f
file     ---->            file03.bin  [f] f
         <---- file       file0A.bin  [f] f
         <---- file       file0B.bin  [f] f
         <---- file       file0C.bin  [f] f

Proceed with propagating updates? [] y
Propagating updates


Unison 2.51.4 (ocaml 4.05.0) started propagating changes at 15:29:09.85 on 06 Jan 2022
[BGN] Copying file01.bin from ~/source to ~/target
[END] Copying file01.bin
[BGN] Copying file02.bin from ~/source to ~/target
[END] Copying file02.bin
[BGN] Copying file03.bin from ~/source to ~/target
[END] Copying file03.bin
[BGN] Copying file0A.bin from ~/target to ~/source
[END] Copying file0A.bin
[BGN] Copying file0B.bin from ~/target to ~/source
[END] Copying file0B.bin
[BGN] Copying file0C.bin from ~/target to ~/source
[END] Copying file0C.bin
Unison 2.51.4 (ocaml 4.05.0) finished propagating changes at 15:29:09.86 on 06 Jan 2022, 0.012 s


Saving synchronizer state
Synchronization complete at 15:29:09  (6 items transferred, 0 skipped, 0 failed)

完了したら、再度同期しようとすると、同期することは何も表示されません。

$ ./unison ~/source/ ~/target/
Unison 2.51.4 (ocaml 4.05.0): Contacting server...
Looking for changes
Reconciling changes
Nothing to do: replicas have not changed since last sync.

一部のファイルを削除または変更して再度同期を試みる場合は、確認を再度行う必要があります。

$ rm source/file0B.bin 
$ echo "edit file" > source/file0C.bin 
$ tree
.
├── source
│   ├── file01.bin
│   ├── file02.bin
│   ├── file03.bin
│   ├── file0A.bin
│   └── file0C.bin
└── target
    ├── file01.bin
    ├── file02.bin
    ├── file03.bin
    ├── file0A.bin
    ├── file0B.bin
    └── file0C.bin

2 directories, 11 files

$ ./unison ~/source/ ~/target/
Unison 2.51.4 (ocaml 4.05.0): Contacting server...
Looking for changes
Reconciling changes

source         target             
deleted  ---->            file0B.bin  [f] 
changed  ---->            file0C.bin  [f] 

Proceed with propagating updates? [] y
Propagating updates


Unison 2.51.4 (ocaml 4.05.0) started propagating changes at 15:50:16.93 on 06 Jan 2022
[BGN] Updating file file0C.bin from ~/source to ~/target
[END] Updating file file0C.bin
[BGN] Deleting file0B.bin from ~/target
[END] Deleting file0B.bin
Unison 2.51.4 (ocaml 4.05.0) finished propagating changes at 15:50:16.93 on 06 Jan 2022, 0.003 s


Saving synchronizer state

対話型プロンプトなしでデフォルトのユニゾン設定との同期をすぐに続行したい場合、競合しない変更が伝播され、競合がスキップされます。オプションとして-batch =trueを渡すことができます

$ ./unison -batch=true ~/source/ ~/target/
Unison 2.51.4 (ocaml 4.05.0): Contacting server...
Looking for changes
Reconciling changes
changed  ---->            file0C.bin  
source       : changed file       modified on 2022-01-06 at 16:40:13  size 11        rw-r--r--
target       : unchanged file     modified on 2022-01-06 at 16:28:13  size 11        rw-r--r--
Propagating updates
Unison 2.51.4 (ocaml 4.05.0) started propagating changes at 16:40:35.93 on 06 Jan 2022
[BGN] Updating file file0C.bin from ~/source to ~/target
[END] Updating file file0C.bin
Unison 2.51.4 (ocaml 4.05.0) finished propagating changes at 16:40:35.93 on 06 Jan 2022, 0.000 s
Saving synchronizer state
Synchronization complete at 16:40:35  (1 item transferred, 0 skipped, 0 failed)

4. Zaloha2Bashスクリプトの使用

4.1. インストール

Zaloha2は、Bashスクリプト形式の小さくてシンプルなディレクトリシンクロナイザーです。 GitHubリポジトリからダウンロードできます。

プロジェクトをダウンロードすると、次のパッケージが提供されます。

$ tree
.
├── DOCUMENTATION.md
├── LICENSE
├── README.md
├── Simple_Demo_screenshot.png
├── Simple_Demo_step1.sh
├── Simple_Demo_step2.sh
├── Simple_Demo_step3.sh
├── Simple_Demo_step4.sh
├── Simple_Demo_step5.sh
├── Simple_Demo_step6.sh
├── Simple_Demo_step7.sh
└── Zaloha2.sh

0 directories, 12 files

Zaloha2.sh を実行可能にする必要があります。これで、使用する準備が整いました。

$ sudo chmod u+x Zaloha2.sh

4.2. 使用法

Zaloha2の使用は非常に簡単です。 まず、次のディレクトリ構造があるとします。

$ tree
.
├── source
│   ├── file01.bin
│   ├── file02.bin
│   └── file03.bin
└── target
    ├── file0A.bin
    ├── file0B.bin
    └── file0C.bin

2 directories, 6 files

次に、同期プロセスを実行します。

$ ./Zaloha2.sh --sourceDir="/home/baeldung/source" --backupDir="/home/baeldung/target" --color --revUp --revNew --noRemove --sha256 --findSourceOps='( -type d -a -name subdir ) -prune -o' --findSourceOps='( -type d -a -name .svn ) -prune -o' --findSourceOps='( -type d -a -name .cache ) -prune -o' --findGeneralOps=

TO BE COPIED TO /home/baeldung/target/
===========================================
NEW       file01.bin
NEW       file02.bin
NEW       file03.bin
MKDIR     subdir2
NEW       subdir2/file05.bin

Execute above listed copies to /home/baeldung/target/ ?
[Y/y=Yes, S/s=do nothing and show further, other=do nothing and abort]: y

    mkdir /home/baeldung/target/subdir2
    cp --preserve=timestamps /home/baeldung/source/file01.bin /home/baeldung/target/file01.bin
    cp --preserve=timestamps /home/baeldung/source/file02.bin /home/baeldung/target/file02.bin
    cp --preserve=timestamps /home/baeldung/source/file03.bin /home/baeldung/target/file03.bin
    cp --preserve=timestamps /home/baeldung/source/subdir2/file05.bin /home/baeldung/target/subdir2/file05.bin

TO BE REVERSE-COPIED TO /home/baeldung/source/
===========================================

FROM COMPARING CONTENTS OF FILES: TO BE COPIED TO /home/baeldung/target/
===========================================
$
$ tree
.
├── source
│   ├── file01.bin
│   ├── file02.bin
│   ├── file03.bin
│   ├── subdir
│   │   └── file04.bin
│   └── subdir2
│       └── file05.bin
└── target
    ├── file01.bin
    ├── file02.bin
    ├── file03.bin
    ├── file0A.bin
    ├── file0B.bin
    ├── file0C.bin
    └── subdir2
        └── file05.bin

5 directories, 12 files

使用するオプションを調べてみましょう。

  • –sourceDir :ソースディレクトリ
  • –backupDir :ターゲットディレクトリ
  • –color :インタラクティブプロンプト中に変更を色付けします
  • –revUp :逆更新; ターゲットに新しいオブジェクトがある場合は、それらをソースにコピーします
  • –revNew :reverse-new; ソースに存在しないオブジェクトがターゲットにあり、それらがZaloha2の最後の実行よりも新しい場合は、それらをソースにコピーします
  • –noRemove :ターゲット内のオブジェクトを削除しません。 ターゲット内の既存のオブジェクトのみを追加または更新します
  • –sha256 :ファイルサイズと変更日を比較するほかに、ファイルSHA256チェックサムをチェックします
  • –noProgress :分析フェーズからのメッセージを表示しません
  • –findSourceOps :特定のサブディレクトリを同期から除外します。 そのようなサブディレクトリがターゲットに存在する場合、それは削除されます
  • –findGeneralOps :空の場合、特定のディレクトリ(”trash”または”lost + found”)を除外する内部定義のデフォルトを無効にします。 findSourceOps の代わりに使用して、ファイルまたはディレクトリを一般的に除外することもできます

rsync やUnisonとは異なり、 Zaloha2は、ファイルまたはディレクトリがZaloha2 の最後の実行よりも新しい場合を除き、最初にターゲットからソースにファイルまたはディレクトリを逆コピーしません。

それでは、ターゲットディレクトリ内のいくつかのファイルを更新してから、Zaloha2を再度実行してリバースコピーをトリガーしましょう。

$ echo "edit" > target/file0B.bin 
$ echo "edit" > target/file0C.bin 
$ echo "edit" > target/subdirB/file0E.bin 
$
$ ./Zaloha2.sh --sourceDir="/home/baeldung/source" --backupDir="/home/baeldung/target" --color --revUp --revNew --noRemove --sha256 --findSourceOps='( -type d -a -name subdir1 ) -prune -o' --findSourceOps='( -type d -a -name subdirA ) -prune -o' --findGeneralOps=

TO BE COPIED TO /home/baeldung/target/
===========================================

TO BE REVERSE-COPIED TO /home/baeldung/source/
===========================================
REV.NEW   file0A.bin
REV.NEW   file0B.bin
REV.NEW   file0C.bin
REV.MKDI  subdirB
REV.NEW   subdirB/file0E.bin

Execute above listed reverse-copies to /home/baeldung/source/ ?
[Y/y=Yes, S/s=do nothing and show further, other=do nothing and abort]: y

    '[' '!' -e /home/baeldung/source/file0A.bin ']'
    '[' '!' -e /home/baeldung/source/file0B.bin ']'
    '[' '!' -e /home/baeldung/source/file0C.bin ']'
    '[' '!' -e /home/baeldung/source/subdirB ']'
    mkdir /home/baeldung/source/subdirB
    '[' '!' -e /home/baeldung/source/subdirB/file0E.bin ']'
    cp --preserve=timestamps /home/baeldung/target/file0A.bin /home/baeldung/source/file0A.bin
    cp --preserve=timestamps /home/baeldung/target/file0B.bin /home/baeldung/source/file0B.bin
    cp --preserve=timestamps /home/baeldung/target/file0C.bin /home/baeldung/source/file0C.bin
    cp --preserve=timestamps /home/baeldung/target/subdirB/file0E.bin /home/baeldung/source/subdirB/file0E.bin

FROM COMPARING CONTENTS OF FILES: TO BE COPIED TO /home/baeldung/target/
===========================================
$
$ tree
.
├── source
│   ├── file01.bin
│   ├── file02.bin
│   ├── file03.bin
│   ├── file0A.bin
│   ├── file0B.bin
│   ├── file0C.bin
│   ├── subdir1
│   │   └── file04.bin
│   ├── subdir2
│   │   └── file05.bin
│   └── subdirB
│       └── file0E.bin
└── target
    ├── file01.bin
    ├── file02.bin
    ├── file03.bin
    ├── file0A.bin
    ├── file0B.bin
    ├── file0C.bin
    ├── subdir2
    │   └── file05.bin
    ├── subdirA
    │   └── file0D.bin
    └── subdirB
        └── file0E.bin

8 directories, 18 files

自動/非対話型モードを設定する場合は、柔軟ではありますが、実装が少し複雑な手順があります。これは、作成者がドキュメントで提案しています。

追加のオプション–noExec を指定してコマンドを実行する必要があります。これにより、スクリプトのみが生成されます(スクリプトはターゲットディレクトリの .Zalora_metadata に保存されます)。 次に、それらのスクリプトを実行するためのラッパースクリプトを作成する必要があります。 自動操作セクションのZaloha2ドキュメントを参照してください。

Zaloha2プロジェクトはまだ活発に開発中です—注意して使用してください

5. FreeFileSyncプログラムの使用

5.1. インストール

FreeFileSync は、オープンソースのマルチプラットフォームソフトウェアです。 GUIベースですが、バッチ/非対話モードを実行する機能も提供します。

FreeFileSyncインストーラースクリプトをホームページからダウンロードして実行すると、デスクトップショートカットが作成されます。

5.2. 使用法

これはFreeFileSyncのメインUIです。

 

インターフェイスは非常に直感的です。

  1. ファイルの変更された時間とサイズ、ファイルの内容、ファイルサイズに基づいて比較するなど、比較設定を変更します。
  2. 2つのディレクトリ間の比較を開始します。
  3. フィルタ:ファイル名、拡張子、サイズ、または変更時刻に基づいて、特定のファイルまたはディレクトリを含めたり除外したりできます。
  4. 同期設定の変更:2方向(双方向)、一方向(ミラー)、更新のみ(更新)、またはカスタムで同期できます。
  5. 同期を開始します。
  6. ソースディレクトリ。
  7. ターゲットディレクトリ。

バッチ/非対話型モードを作成する場合は、最初にソースディレクトリとターゲットディレクトリを選択してから、ファイル>バッチジョブとして保存…をクリックする必要があります。これにより、次のダイアログが表示されます。

進行状況ダイアログオプションを無効にし、エラーを無視オプションを有効にする必要があります。 それ以外の場合は、対話型/エラーメッセージボックスが表示され、対話を無期限に待機します。

バッチジョブファイルを作成した後、例えば BatchRun.ffs_batch 、それを実行するためにFreeFileSyncを設定する必要があります。

たとえば、cronジョブを毎日午前1時に実行するように設定できます。

$ crontab -e

0 1 * * * <FreeFileSync installation path>/FreeFileSync <batch file path>/BatchRun.ffs_batch

6. 比較

6.1. 特徴

道具 プログラミング言語 ライセンス 双方向 デルタコピー 競合を検出する 削除の伝播 リビジョン管理 スケジューリングまたはサービス
rsync C GPL v3 はい はい はい はい、 –deleteを使用します はい、 –backupとタイムスタンプ付きの–suffixを使用します はいOS経由
ユニゾン 主にOCaml GPL はい はい はい はい はい はいOS経由
Zaloha2 バッシュ MIT はい はい いいえ はい はい はいOS経由
FreeFileSync C ++ GPL はい はい はい はい はい はいOS経由

6.2. 基準

次のシステムとデータでパフォーマンスを測定しました。

  • Dell Latitude Intel Core i7-6600U CPU @ 2.60GHz×4、16GB RAM
  • ソースディレクトリ:Seagate外付けHDD 5TB、7200rpm、SATA III、ext4
  • ターゲットディレクトリ:Seagate外付けHDD 1.5TB、7200rpm、SATA III、NTFS
  • 同期されたデータ:10GB、11,780ファイル
  • OS:Debianバスター

ソースディレクトリのファイル数と合計サイズは次のとおりです。

$ find source -type f | wc -l
11780
$
$ du source -hc --max-depth=0
1.3G source/subdir1
3.3G source/subdir2
5.5G source/subdir3
10G source
10G total

コマンドを3回実行して各アプローチをテストしました rsync を除く– 6回–双方向ではないため):

  • 最初の実行では、sourceからtargetディレクトリにデータを同期/ミラーリングしました。
  • 2回目の実行では、何もする必要がないため、すべてのツールがすぐに返されました。
  • 次に、3回目の実行では、最初に source のデータを削除( subdir1 を削除)し、データを追加(subdir1の名前をsubdir4に変更)しました。 ) target で、ディレクトリを同期しました。

各コマンドに使用したオプション:

  • rsync
    $ rsync -PScauv --info=progress2 source/ /media/baeldung/target/
    $ rsync -PScauv --info=progress2 target/ /media/baeldung/source/
  • ユニゾン
    $ ./unison -batch=true /media/baeldung/source/ /media/baeldung/target/
  • Zaloha2
    $ ./Zaloha2.sh --sourceDir="/media/baeldung/source" --backupDir="/media/baeldung/target" --color --revUp --revNew --noRemove --noRestore --mawk --findGeneralOps=
  • FreeFileSync
    $ which FreeFileSync
    /home/baeldung/.local/bin/FreeFileSync
    $ ./home/baeldung/.local/bin/FreeFileSync BatchRun.ffs_batch

結果:

道具 ファーストラン 2回目の実行 3回目の実行
rsync 15:44 00:01 15:48
ユニゾン 07:31 00:01 00:04
Zaloha2 05:22 00:01 失敗(逆更新なし)
FreeFileSync 05:10 00:01 00:13

7. 結論

テストした4つのツールすべての中で、Unisonが双方向のディレクトリの同期に最適であることがわかりました。

ユニゾンを初めて実行する場合は時間がかかる場合がありますが、パフォーマンスの点では、その後の実行が他のツールと比較して最速でした。 競合の検出をサポートし、障害に対する耐性があり(リビジョン管理があり、ロールバックに役立ちます)、双方向であり、コマンドラインとGUIインターフェイスを備えています。

すぐに来るのはFreeFileSyncです。これは、直感的なGUIにも優れています。