使用 diff -r 递归比较两个目录,而不在损坏的链接上输出

使用 diff -r 递归比较两个目录,而不在损坏的链接上输出

我在用diff -r a b递归比较目录A。尽管存在一些损坏的链接(两个中的相同损坏链接),但经常会发生这种情况A目录并指向相同的、不存在的目标)。

差异然后输出这些情况的错误消息并以非零退出代码退出,但是我希望它保持沉默,并以 0 退出,因为目录在我的书中是相同的。

我怎样才能做到这一点?

答案1

对于 3.3 或更高版本diff,您应该使用该--no-dereference选项,如中所述皮特·哈伦的回答

不幸的是,旧版本diff 不支持忽略符号链接:

有些文件既不是目录也不是常规文件:它们是不寻常的文件,例如符号链接、设备特殊文件、命名管道和套接字。目前,diff将符号链接视为常规文件;如果在顶层指定了其他特殊文件,它会将它们视为常规文件,但在比较目录时仅报告它们的存在。这意味着patch不能代表对此类文件的更改。例如,如果更改符号链接指向的文件,diff则输出两个文件之间的差异,而不是对符号链接的更改。

diff应该选择专门报告对特殊文件的更改,并且patch应该进行扩展以了解这些扩展。

如果您想要的只是验证 rsync(并且可能修复丢失的内容),那么您可以再次运行 rsync 命令。如果你不想这样做,那么对目录进行校验和可能就足够了。

如果您确实想使用 执行此操作diff,则可以使用find跳过符号链接,并对每个文件单独运行 diff。传递你的目录A作为参数:

#!/bin/bash
# Skip files in $1 which are symlinks
for f in `find $1/* ! -type l`
do
    # Suppress details of differences
    diff -rq $f $2/${f##*/}
done

或作为单行:

for f in `find a/* ! -type l`;do diff -rq $f b/${f##*/};done

这将识别内容不同的文件,或A但不在

注意:

  • 由于我们完全跳过符号链接,因此不会注意到符号链接名称是否不存在于。如果您需要这样做,则需要第二次查找过程来识别所有符号链接,然后显式检查它们是否存在于
  • 额外文件位于不会被识别,因为该列表是根据以下内容构建的A。对于您的场景来说,这可能不是问题rsync

答案2

从版本 3.3 开始,GNUdiff支持不取消引用符号链接,而是比较它们指向的路径。

安装 GNU diffutils>= 3.3 并使用该--no-dereference选项;对此没有简短的选择。

如果等于或以下情况,诊断将保持沉默:

符号链接/tmp/noderef/a/symlink/tmp/noderef/b/symlink不同

答案3

您可以使用较新版本的diff

diffGNU diffutils3.3 中包含一个选项--no-dereference,允许您比较符号链接本身而不是它们的目标。如果它们不同,它会报告;如果它们同意,它会保持安静,并且不关心它们是否被破坏。

我不知道这个选项是什么时候添加的;它在 2.8.1 中不存在。

答案4

此代码比较两个文件夹中的文件,但使用第一个文件夹的文件名作为基线

diffDir() {
    A=$1
    B=$2
    for src in `find $A ! -type l` ; do
        dst=/data/f-stack/freebsd/${src#$A}
        if [ -f $dst ]; then
            GIT_PAGER= git diff --no-ext-diff $src $dst;
        fi
    done
}

diffDir /data/freebsd/freebsd11.0/sys/ /data/f-stack/freebsd/

相关内容