web-dev-qa-db-ja.com

コマンドラインツールで2つのフォルダーを同期する方法

WindowsからLinuxに移行した後、Winmergeの代替ソフトウェアを見つけるか、Linux上の2つのフォルダーを比較および同期するコマンドラインツールについて学びたいと思います。コマンドラインで次のタスクを実行する方法を教えていただければ幸いです...(私はdiffとrsyncを研究しましたが、それでもいくつかの助けが必要です。)

「/ home/user/A」と「/ home/user/B」の2つのフォルダーがあります。

フォルダーAは通常のファイルとフォルダーが保存される場所で、フォルダーBはフォルダーAの完全なミラーとして機能するバックアップフォルダーです(ユーザーがフォルダーBに直接保存または変更するものはありません)。

私の質問は:

  • フォルダBにのみ存在するファイルを一覧表示する方法は? (例:前回の同期以降にフォルダーAから削除されたもの)

  • フォルダーBにのみ存在するファイルをコピーしてフォルダーAに戻す方法は?

  • 両方のフォルダーに存在するが、タイムスタンプまたはサイズが異なるファイルを一覧表示する方法は? (前回の同期以降にフォルダーAで変更されたもの。チェックサムの使用は避けたい。何万ものファイルがあり、プロセスが遅すぎるため。)

  • フォルダーAの正確なコピーをフォルダーBに作成する方法は?つまり、フォルダーAからフォルダーAにのみ存在するフォルダーBにすべてをコピーし、フォルダーBにのみ存在するフォルダーBからすべてを削除しますが、両方のフォルダーで同じファイルには触れません。

79
akopacsi

これにより、フォルダーAがフォルダーBに配置されます。

rsync -avu --delete "/home/user/A" "/home/user/B"  

フォルダAとBの内容を同じにする場合は、/home/user/A/(スラッシュ付き)をソースとして使用します。これはフォルダーAではなく、そのすべてのコンテンツを取得し、フォルダーBに入れます。

rsync -avu --delete "/home/user/A/" "/home/user/B"
  • -aすべてのファイルシステム属性を保持して同期を行います
  • -v冗長に実行
  • -uより新しい変更時刻(または時刻が等しい場合はサイズの違い)を持つファイルのみをコピーします
  • --deleteソースに存在しないターゲットフォルダ内のファイルを削除します

マンページ: https://download.samba.org/pub/rsync/rsync.html

106
TuxForLife

Uペンのベンジャミンピアスによって開発されたunisonツールを使用できます。

2つのディレクトリがあるとします。

_/home/user/Documents/dirA/_および_/home/user/Documents/dirB/_

これら2つを同期するには、以下を使用できます。

〜$ _unison -ui text /home/user/Documents/dirA/ /home/user/Documents/dirB/_

出力では、unisonは、同期を要求した2つのディレクトリでdifferentであるすべてのディレクトリとファイルを表示します。最初の実行時に追加同期(両方の場所で欠落しているファイルを複製)を行うことをお勧めします。その後、マシン上で同期ツリーを作成して維持し、その後の実行で真の同期を実装します(つまり、_.../dirA_、それは_.../dirB_からも削除されます。また、すべての変更を比較し、オプションでforwardまたはreverse2つのディレクトリ間で同期します。

必要に応じて、グラフィカルインターフェイスを起動するには、コマンドから_-ui text_オプションを削除するだけですが、cliの方が簡単で高速です。

これについての詳細: nisonユーザードキュメントのUnisonチュートリアル

12
axolotl

これは、個人ファイルのバックアップに使用しているもので、-aでカバーされるすべてのことは気にせず、より有用な情報を印刷したいと考えています。

rsync -rtu --delete --info=del,name,stats2 "/home/<user>/<src>/" "/run/media/<user>/<drive>/<dst>"

rsync manページ から:

-r、-recursive
これは、ディレクトリを再帰的にコピーするようにrsyncに指示します。

-t、-times
これにより、rsyncはファイルと一緒に変更時刻を転送し、リモートシステムでそれらを更新します。

-u、-update
これにより、rsyncは宛先に存在し、ソースファイルよりも変更時刻が新しいファイルをスキップします。 (既存の宛先ファイルの変更時間がソースファイルの変更時刻と同じ場合、サイズが異なると更新されます。)

-削除
これは、rsyncに受信側(送信側にないファイル)から無関係なファイルを削除するように指示しますが、同期されているディレクトリに対してのみです。

--info = FLAGS
このオプションを使用すると、表示する情報出力をきめ細かく制御できます。

rsync --info=helpから

DEL        Mention deletions on the receiving side  
NAME       Mention 1) updated file/dir names, 2) unchanged names  
STATS      Mention statistics at end of run (levels 1-3)

それほど明確ではありませんが、これは一見同等で短くなっています。

rsync -rtuv --delete --info=stats2 "/home/<user>/<src>/" "/run/media/<user>/<drive>/<dst>"

-v、-verbose
-vを1つ指定すると、転送されているファイルに関する情報と、最後に要約が表示されます[stats1]。

1
Honest Abe

TuxForLifeからの答えはかなり良いですが、ローカルで同期するときは-cを使用することを強くお勧めします。リモート同期の場合は、時間/ネットワークのペナルティに値しないと主張できますが、速度が非常に高いため、ローカルファイルの場合はそれだけの価値があります。

-c, --checksum
       This forces the sender to checksum every regular file using a 128-bit  MD4
       checksum.   It  does this during the initial file-system scan as it builds
       the list of all available files. The receiver then checksums  its  version
       of  each  file  (if  it exists and it has the same size as its sender-side
       counterpart) in order to decide which files need to be updated: files with
       either  a  changed  size  or a changed checksum are selected for transfer.
       Since this whole-file checksumming of all files on both sides of the  con-
       nection  occurs  in  addition to the automatic checksum verifications that
       occur during a file's transfer, this option can be quite slow.

       Note that rsync always verifies that each transferred file  was  correctly
       reconstructed  on  the receiving side by checking its whole-file checksum,
       but that automatic after-the-transfer verification has nothing to do  with
       this  option's  before-the-transfer  "Does  this file need to be updated?"
       check.

これは、同じサイズとタイムスタンプを使用すると失敗する可能性があることを示しています。

セットアップ

$ cd /tmp

$ mkdir -p {A,b}/1/2/{3,4}

$ echo "\___________from A" | \
      tee A/1/2/x  | tee A/1/2/3/y  | tee A/1/2/4/z  | \
  tr A b | \
      tee b/1/2/x  | tee b/1/2/3/y  | tee b/1/2/4/z  | \
      tee b/1/2/x0 | tee b/1/2/3/y0 >     b/1/2/4/z0

$ find A b -type f | xargs -I% sh -c "echo %; cat %;"
A/1/2/3/y
\___________from A
A/1/2/4/z
\___________from A
A/1/2/x
\___________from A
b/1/2/3/y
\___________from b
b/1/2/3/y0
\___________from b
b/1/2/4/z
\___________from b
b/1/2/4/z0
\___________from b
b/1/2/x
\___________from b
b/1/2/x0
\___________from b

すべてのファイルのサイズとタイムスタンプが同じであるため、何もコピーしないrsync

$ rsync -avu A/ b
building file list ... done

sent 138 bytes  received 20 bytes  316.00 bytes/sec
total size is 57  speedup is 0.36

$ find A b -type f | xargs -I% sh -c "echo %; cat %;"
A/1/2/3/y
\___________from A
A/1/2/4/z
\___________from A
A/1/2/x
\___________from A
b/1/2/3/y
\___________from b
b/1/2/3/y0
\___________from b
b/1/2/4/z
\___________from b
b/1/2/4/z0
\___________from b
b/1/2/x
\___________from b
b/1/2/x0
\___________from b    

チェックサムを比較するため正しく動作するrsync

$ rsync -cavu A/ b
building file list ... done
1/2/x
1/2/3/y
1/2/4/z

sent 381 bytes  received 86 bytes  934.00 bytes/sec
total size is 57  speedup is 0.12

$ find A b -type f | xargs -I% sh -c "echo %; cat %;"
A/1/2/3/y
\___________from A
A/1/2/4/z
\___________from A
A/1/2/x
\___________from A
b/1/2/3/y
\___________from A
b/1/2/3/y0
\___________from b
b/1/2/4/z
\___________from A
b/1/2/4/z0
\___________from b
b/1/2/x
\___________from A
b/1/2/x0
\___________from b
1
Bruno Bronosky

次のように使用できます。

rsync -avu --delete /home/user/A/* /home/user/B/

この方法では、フォルダーA自体のコンテンツではなく、フォルダーAのコンテンツをフォルダーBにコピーします。

0
Isaias Sanchez

これは要求するものと完全に同じではありませんが、バージョン管理ツールの使用を検討することができます。 Gitのようなツールは、必要なすべてのことを実行します。特に、フォルダーBで直接作業しない場合は、それを見てみると興味深いかもしれません。 git here に関する詳細情報を見つけることができます

0
switch87

あなたは Fitus/Zaloha.sh を見ているかもしれません。これは、標準のUnixコマンドのみを使用するbashシェルスクリプトとして実装されたシンクロナイザです。使い方は簡単です:

$ Zaloha.sh --sourceDir="test_source" --backupDir="test_backup"
0
user380458