可以找到从 -exec 可靠地调用自身而不破坏两个实例的语义吗?

可以找到从 -exec 可靠地调用自身而不破坏两个实例的语义吗?

下列的http://superuser.com/questions/1780479http://superuser.com/questions/1777606,我们发出以下脚本来比较目录 $1 和 $2 下相同全路径符号链接的时间:

#!/bin/bash
cd $1
find . -type l -exec bash -c "if [[ -h \"{}\" && -h \"$2/{}\" ]]; then if (test $(readlink \"{}\") = $(readlink \"$2/{}\")) then if (find \"$2/{}\" -prune -newer \"{}\" -printf 'a\n' | grep -q a) then echo \"{} is older than $2/{}\"; else if (find \"{}\" -prune -newer \"$2/{}\" -printf 'a\n' | grep -q a) then echo \"$2/{} is older than {}\"; fi; fi; fi; fi" \;

用法是Compare_times.sh 目录_1 目录_2(其中compare_times.sh是脚本的名称)。我们按以下示例所示使用它:

user@machine:/tmp/D1$ ls -lt --full-time /tmp/linked_file /tmp/D*
-rw-r--r-- 1 user user  0 2023-04-25 00:12:09.289942358 +0200 /tmp/linked_file

/tmp/D2:
total 0
lrwxrwxrwx 1 user user 14 2023-04-25 00:07:00.265830604 +0200 lnk -> ../linked_file

/tmp/D1:
total 0
lrwxrwxrwx 1 user user 14 2023-04-25 00:06:40.922078186 +0200 lnk -> ../linked_file
user@machine:/tmp/D1$ compare_times.sh . ../D2
./lnk is older than ../D2/./lnk
user@machine:/tmp/D1$

如您所见,find调用bash,它本身也调用find。 (也许,这样写起来会更优雅,但这不是现在的重点。)findfind这种方式下调用有什么问题吗?

该命令的手册页find没有说明是否find可重入。如果find不可重入,假设我们可能会默默地错过一些输出,即一些在两个目录中具有相同名称和相同位置的符号链接,并且指向相同的文件名但具有不同的时间戳。

答案1

并非所有命令都可以重新输入。

你在想哪些?

通常,可重入性对于隐式使用某些全局状态的库函数会产生问题,并且同时调用该函数两次(例如从其自身内部调用该函数会弄乱该状态)。 (参见例如为什么说malloc()和printf()是不可重入的?就这样。)

但是各个进程之间没有全局状态,它们都有自己的内存空间和操作系统,并且硬件确保进程不会弄乱其他进程的内存。当然,例如文件系统是全局状态,但我不确定find是否需要使用它来保存状态,无论如何,确实需要临时文件的受人尊敬的程序通常非常擅长使用唯一的临时文件。

如果文件系统中的状态是一个问题,则很难看出它如何特定find于称为彼此子进程的进程,但它已经开始运行任何并发find进程。


从另一个运行一个文件有多大用处find是另一个问题,但我想您可以这样做来查找名为x...的目录下的所有常规文件。

$ mkdir -p {a/x,b,x}; touch {a/x,b,x}/foo.txt
$ find . -type d -name x -exec find {} -type f \;;
./a/x/foo.txt
./x/foo.txt

相关内容