热衷于让 diff 检查符号链接本身?

热衷于让 diff 检查符号链接本身?

在Linux中可以使用该命令diff来检查文件的差异。我用它来检查两个模块之间的差异,两个模块都复制到/tmp.

但是,这两个模块都有符号链接,可能未指向正确的文件,因为模块已复制到目录中/tmp。但这并不重要。我想检查的是符号链接是否相同。

例如,在一个模块中,符号链接为

/home/test/file1

在另一个中,符号链接如下:

/etc/rc.d/whatever

diff现在会抛出错误,因为通常来说它找不到该文件。但我想说diff:“嘿,这些符号链接不一样”,无论链接是否指向有效文件。

问题:如何才能diff做到这一点,即不尝试跟踪链接,而是区分链接本身?

答案1

尝试diff使用 GNU 3.3 或更高版本的--no-dereference选项(大概还有 --recursive 选项):

diff --recursive --no-dereference tree1root tree2root

--no-dereference将阻止diff跟踪任何符号链接。它仍然会比较目标并让您知道它们是否不同。

答案2

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

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

如果路径相等,则诊断将保持沉默,或者:

Symbolic links /tmp/noderef/a/symlink and /tmp/noderef/b/symlink differ

如果路径不同。

答案3

使用 GNU 工具:

diff <(cd dir1 && find . -type l -printf '%p -> %l\n'|sort) \
     <(cd dir2 && find . -type l -printf '%p -> %l\n'|sort)

严格来说,这无法区分称为a指向的符号链接b -> c和称为a -> b指向的符号链接c,更不用说包含换行符的文件名的问题,但这使得输出比更强大的输出更清晰:

diff <(cd dir1 && find . -type l -printf '%p // %l\0'|tr '\n\0' '\0\n'|sort) \
     <(cd dir2 && find . -type l -printf '%p // %l\0'|tr '\n\0' '\0\n'|sort)

在那里,我们使用//分隔符(否则不会出现在findfor的输出中%p)并将换行符转换为 NUL 字符(这不会出现在%pNor的扩展中%l)。

答案4

如果我理解正确,您需要检查符号链接是否指向相同的理论目的地,或者如果一个不是符号链接,则另一个文件链接到同一文件。这应该做你想要的:

#!/bin/bash

if [[ "$(readlink -m -- "$1")" == "$(readlink -m -- "$2")" ]]; then
    echo "files match"
else
    echo "files don't match"
    exit 1
fi
$ > foo 
$ ln -s foo bar
$ ln -s foo baz
$ ./script bar baz
files match
$ ./script bar foo
files match
$ ln -sf qux bar
$ ./script bar foo
files don't match

相关内容