在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)
在那里,我们使用//
分隔符(否则不会出现在find
for的输出中%p
)并将换行符转换为 NUL 字符(这不会出现在%p
Nor的扩展中%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