user@debian:~/test/B$ find ..
..
../A
../A/x
../A/y
../A/z
../B
user@debian:~/test/B$ find ../A -type f -print0 |xargs -0 -i% realpath --relative-to=../A %
x
y
z
user@debian:~/test/B$ # But
user@debian:~/test/B$ find ../A -type f -print0 |xargs -0 -i% echo $(realpath --relative-to=../A %)
../B/../A/x
../B/../A/y
../B/../A/z
穆鲁建议问题的答案“带有基本名称的 find -exec 命令选项“可能会回答这个问题,但我没有使用find
with -exec
。
我不明白 muru 的解释“命令替换realpath
是由 shell 在开始运行之前执行的xargs
(作为评估参数应该xargs
是什么的一个步骤)”:
realpath --relative-to=../A
在调用之前如何进行评估xargs
?- 即使它被评估,它的评估结果是什么,为什么会导致不同的输出?
答案1
解释
感谢@muru 引导我找到自己的答案。这是正在发生的事情:
当 shell 看到命令行时
find ../A -type f -print0 |xargs -0 -i% echo $(realpath --relative-to=../A %)
它首先评估命令替换
realpath --relative-to=../A %
其评估结果为../B/%
.
因此启动时执行的有效命令find
是:
find ../A -type f -print0 |xargs -0 -i% echo ../B/%
realpath
...它根本不调用,而只是将find
输出附加到../B/
.
解决方法
不要在那里使用命令替换,realpath
在做你想做的事情之前使用 plain 来完成它的工作(在这个例子中不是很多,但这显然可以扩展):
find ../A -type f -print0 |xargs -0 -i% realpath -z --relative-to=../A % |xargs -0 -i% echo %