我想检查链接是否lnkfile
比常规参考文件旧reffile
。
bashtest
内置取消引用链接,因此test lnkfile -ot reffile
比较 的目标lnkfile
,而不是链接本身。
有没有办法让test
内置函数不遵循符号链接?否则,我如何比较符号链接的时间?
答案1
我不认为有办法使用test
,但你可以使用find
。
test "$(find reffile -prune -newer lnkfile)" && command
此处,如果早于 则find
返回输出。没有选项相当于.如果字符串的长度不为零,则这是正确的。因此,如果有输出,则执行。lnkfile
reffile
test
test -n
find
command
在评论中,我被要求对此解决方案与其他解决方案进行比较。stat
。首先,我发现这种stat
方法非常好。
我做了一个基准测试来比较。我交替重复测试几次,得到了相似的结果。
$ time (for i in {1..1000}; do test "$(stat --format=%Z a)" -lt "$(stat --format=%Z b)" && echo foo > /dev/null ; done)
================
CPU 101%
CPU 104%
user 1.264
system 0.942
total 2.108
$ time (for i in {1..1000}; do test "$(find b -newer a)" && echo foo > /dev/null ; done)
================
CPU 104%
user 0.693
system 0.526
total 1.164
我看起来find
几乎快了一倍,也许是因为它是一个进程而不是两个进程stats
?我不知道如何比较它们;如果您能想到其他相关方面,请发表评论。
根据下面 Stéphane Chazelas 的评论,还有一些其他差异:
其他区别是:
find
一个是标准的。而stat
需要 GNU 实现stat
.该stat
方法不适用于同一秒内修改的文件(而find
应该适用于支持时间戳亚秒粒度的系统)。既不find
也不stat
支持任意文件名。如果其中一个文件无法
stat()
编辑,您会发现其他差异。
答案2
据我所知,bash 不提供任何-ot
避免取消引用符号链接的版本(等)。
你可以做的是使用 GNU stat (如果没有 ,它不会取消引用符号链接-L
)并以数字方式比较它们的 mtime 纪元:
if (( "$(stat --format=%Z lnkfile)" < "$(stat --format=%Z reffile)" )); then
# lnkfile is older
fi
答案3
对于zsh
5.6 或更高版本(对于纳秒精度),您只能使用内置函数来实现:
zmodload zsh/stat
if
stat -LA lnktime -F '%021s%N' +mtime -- $lnkfile &&
stat -A reftime -F '%021s%N' +mtime -- $reffile &&
[[ $lnktime < $reftime ]]
then
print -r -- $lnkfile is older than $reffile
fi
无论文件名包含什么字符或非字符,它都可以工作,并将时间戳比较到纳秒。
我们将时间戳作为字符串(纳秒数作为十进制字符串表示形式,用零填充到 30 位数字)而不是浮点进行比较,因为运行 GNU/Linux 的 x86_64 PC 的典型双精度浮点至少没有足够的精确存储数字,1548195897.775033155
这样您就无法在相同的 100 纳秒内区分今天修改的两个文件。
$ ((1548195897.775033155 < 1548195897.775033255)) && echo yes
$ [[ 1548195897775033155 < 1548195897775033255 ]] && echo yes
yes