比较符号链接的时间

比较符号链接的时间

我想检查链接是否lnkfile比常规参考文件旧reffile

bashtest内置取消引用链接,因此test lnkfile -ot reffile比较 的目标lnkfile,而不是链接本身。

有没有办法让test内置函数不遵循符号链接?否则,我如何比较符号链接的时间?

答案1

我不认为有办法使用test,但你可以使用find

test "$(find reffile -prune -newer lnkfile)" && command

此处,如果早于 则find返回输出。没有选项相当于.如果字符串的长度不为零,则这是正确的。因此,如果有输出,则执行。lnkfilereffiletesttest -nfindcommand


在评论中,我被要求对此解决方案与其他解决方案进行比较。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

对于zsh5.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

相关内容