web-dev-qa-db-ja.com

rsyncはディレクトリを比較しますか?

2つのディレクトリをrsyncで比較し、違いのみを出力することは可能ですか?模擬オプションがありますが、詳細度を特定のレベルに上げると、比較されたすべてのファイルが表示されます。

ls -alRdiffはここではオプションではありません。ソースにハードリンクがあり、すべての行が異なるためです。 (もちろん、この列はPerlで削除できます。)

70
chris

おそらく、双方向でrsync -avun --deleteのようなものを実行する必要があります。

しかし、実際に何を達成しようとしていますか?

更新

rsync -avun --delete $TARGET $SOURCE |grep "^deleting "は、ターゲットディレクトリに存在しないファイルのリストを提供します。

"grep delet"各行が出力されるため:delet ing ..file ..

rsync -avun $SOURCE $TARGETは、「異なる」ファイル(新しいファイルを含む)のリストを提供します。

49
Nils

Nilsの回答に追加するため(Google経由でこれに遭遇した人のために)、デフォルトではrsyncはファイルサイズと変更時間のみを比較して、違いがあるかどうかを判断します。 (それらが異なる場合、より多くのことを行いますが、同じである場合、そこで停止します。)

実際のファイルcontentsを比較する場合は、同じサイズで最終変更時刻のファイルでも、フラグ-cを追加してrsyncにファイルを比較するように指示しますチェックサム。

rsync -avnc $SOURCE $TARGET

-uオプションは、$TARGETよりも$SOURCEの方が新しいファイルを無視するようにrsyncに指示します。これは、内容を比較している場合はおそらく不要です。)

53
user98393

rsyncにあまり詳しくない人のために:

rsync -rvnc --delete ${SOURCE}/ ${DEST}
  • -n:最も重要なビット-実行not何かを変更;
  • -rc:内容のみを比較します(それ以外の場合は-acを使用します);
  • -v:ファイルを一覧表示します)
  • --delete:単方向の違いではなく、対称的な違いを探します。
  • 最後に、/は、「ディレクトリ内を見て、そのcontentsを宛先と比較する」ことを意味します。

通常のrsync出力を出力します、

  • ${SOURCE}のすべての「新しい」ファイルの行に1つの<filename>
  • ${DEST}の「新しい」ファイルごとに1つの"deleting <filename>"行。

  • また、シンボリックリンクに対して"通常でないファイル<filename>"のようないくつかの警告を出力する場合もあります。

PS。私はそれがひどいPSであることを知っています-それは確かにラッシュで追加されました。それにもかかわらず、私はこれが便利だと思うかもしれません。


find $SOURCE -type f -exec md5sum {} \; | tee source.md5
find $DEST   -type f -exec md5sum {} \; | tee dest.md5

ファイル名に改行が含まれていない場合は、*.md5ファイルとdiffの両方を並べ替えることができます。 (ただし、これはファイルに対してのみ機能します。つまり、どちらかの側の空のディレクトリは検出されません。)

29
ジョージ

驚くべきことに、6年間で-iオプションを使用したり、Nice出力を提供したりする答えはないので、ここで説明します。

TLDR-コマンドを表示するだけ

rsync -rin --ignore-existing "$LEFT_DIR"/ "$RIGHT_DIR"/|sed -e 's/^[^ ]* /L             /'
rsync -rin --ignore-existing "$RIGHT_DIR"/ "$LEFT_DIR"/|sed -e 's/^[^ ]* /R             /'
rsync -rin --existing "$LEFT_DIR"/ "$RIGHT_DIR"/|sed -e 's/^/X /'

出力について

次に出力の例を示します。

L             file-only-in-Left-dir
R             file-only-in-right-dir
X >f.st...... file-with-dif-size-and-time
X .f...p..... file-with-dif-perms

各行の最初の文字に注意してください:

  • L/Rは、ファイル/ディレクトリがLeftまたはRightディレクトリにのみ表示されることを意味します。
  • Xは、ファイルが両面に表示されるが同じではないことを意味します(この場合、次の11文字で詳細がわかります。stおよびps ize、t ime、およびp ermissionsの違いをそれぞれ示します-詳細については、man rsyncを試して--itemize-changesを検索してください)。

使用したい追加オプション

ファイルの所有者/グループ/権限も比較する場合は、オプション-o/-g/-pをそれぞれ追加します。最後に、デフォルトでは、rsyncは2つのファイルが同じ名前、時間、サイズである場合、それらを同じと見なします。これは非常に高速で、ほとんどの場合は十分以上ですが、100%になりたい場合は、-cを追加して、同じ名前、時間、サイズのファイルの内容も比較してください。

TLDR-呼び出すスクリプトを教えて

ここにあります。このように呼ぶ

diff-dirs Left_Dir Right_Dir [options]

上記の「使用したい追加オプション」で説明したすべてのオプションがここでも適用されます。

#!/bin/bash
# Compare two directories using rsync and print the differences
# CAUTION: options MUST appear after the directories
#
# SYNTAX
#---------
# diff-dirs Left_Dir Right_Dir [options]
#
# EXAMPLE OF OUTPUT
#------------------
# L             file-only-in-Left-dir
# R             file-only-in-right-dir
# X >f.st...... file-with-dif-size-and-time
# X .f...p..... file-with-dif-perms
#
# L / R mean that the file/dir appears only at the `L`eft or `R`ight dir. 
#
# X     means that a file appears on both sides but is not the same (in which
#       case the next 11 characters give you more info. In most cases knowing
#       that s,t,T and p depict differences in Size, Time and Permissions 
#       is enough but `man rsync` has more info
#       (look at the --itemize-changes option)
#
# OPTIONS
#---------
# All options are passed to rsync. Here are the most useful for the purpose
# of directory comparisons:
#
# -c will force comparison of file contents (otherwise only
#    time & size is compared which is much faster)
#
# -p/-o/-g will force comparison of permissions/owner/group

if [[ -z $2 ]] ; then
    echo "USAGE: $0 dir1 dir2 [optional rsync arguments]"
    exit 1
fi

set -e

LEFT_DIR=$1; shift
RIGHT_DIR=$1; shift
OPTIONS="$*"

# Files that don't exist in Right_Dir
rsync $OPTIONS -rin --ignore-existing "$LEFT_DIR"/ "$RIGHT_DIR"/|sed -e 's/^[^ ]* /L             /'
# Files that don't exist in Left_Dir
rsync $OPTIONS -rin --ignore-existing "$RIGHT_DIR"/ "$LEFT_DIR"/|sed -e 's/^[^ ]* /R             /'
# Files that exist in both dirs but have differences
rsync $OPTIONS -rin --existing "$LEFT_DIR"/ "$RIGHT_DIR"/|sed -e 's/^/X /'

どのように機能しますか?

次のようにrsyncを呼び出します。

rsync -rin ...

-i--itemize-changes)を使用して、2つのディレクトリの違いに関する情報を含むすべてのファイルの出力を1行出力するようにrsyncに指示します。 rsyncの通常の動作を抑制するために-nが必要です(ファイルをコピー/削除して2つのディレクトリを同期しようとします)。また、すべてのファイル/サブディレクトリに対して-rを再帰的に動作させる必要があります。

Rsyncを3回呼び出します。

1回目の呼び出し:Dir_Bに存在しないファイルを印刷します。両側に存在するファイルを無視するには、--ignore-existingを使用する必要があります。

rsync -rin --ignore-existing $DIR_A/ $DIR_B/

2回目の呼び出し:まったく同じですが、DIR_A/DIR_Bの順序を入れ替えます。

回目の呼び出し:最後に、--existingを使用して、両方のディレクトリに表示されるファイルのみをチェックします。

rsync -rin --existing $DIR_A/ $DIR_B/
20
ndemou

あなたの質問から、diff on lsを使用したくないことを理解していますが、ディレクトリでdiffを再帰的に使用することもできます。

diff -rq DIR1 DIR2
11
Camion

これを機能させるために数回の試行が必要でした。ジョージの説明によると、Nilsの回答では、$TARGETが末尾の/で終わる必要があります。

これは、末尾に/を明示的に追加するバージョンです。

rsync -avun --delete ${TARGET}/ ${SOURCE}  | sed -ne 's/^deleting *//p'

これにより、${SOURCE}ディレクトリの下には存在するが、${TARGET}ディレクトリの下には存在しないファイルのリストが表示されます。

ここではsedを使用して、出力行から先頭のdeletingを削除し、それらの行のみを出力しています。

rsyncオプション-cは使用していません。これは、ファイルの内容を比較すると、ユースケースがはるかに遅くなり、ファイルサイズと変更時間のみを比較することも、これらのケースでは十分に思えるからです。私のコンピュータがクロックスキューの問題に苦しんでいるか、何かが悪意を持ってタイムスタンプを変更したと疑う理由はありません。また、-cの結果は、ファイルを削除する決定を変更することはできません。ファイルを更新または保持する決定のみを変更できます。

また、-u-aを使用して(-rではなく)、後でコマンドラインを再利用して、選択したディレクトリとファイルを${SOURCE}からコピーするように変更できるようにしています次のように${TARGET}に:

rsync -avu ${SOURCE}/{dirA,dirB,fileX} ${TARGET}   # copy some files
2
Orafu

これを行う別のアイデアがあります:

rsync -rn --out-format=FILEDETAIL::%n  $TARGET $SOURCE  | grep "^FILEDETAIL"

「FILEDETAIL ::」をコマンドの出力と一致させることができます。また、文字列「FILEDETAIL ::」を変更できます。 「%n」はファイル名です。

rsync manpage で述べたように:

-r, --recursive             recurse into directories

-n, --dry-run               perform a trial run with no changes made
0
zhao Tony