为什么在 xargs -I 传递给 sh 的参数之前需要双破折号才能正常工作?

为什么在 xargs -I 传递给 sh 的参数之前需要双破折号才能正常工作?

这是有问题的命令

 find . -name "*.txt" | xargs -Ifile sh -c 'echo $(basename $1) ' -- file

因此,如果没有双破折号,则file不会传递给sh,然后被识别为$1。这是为什么?我知道这--会阻止后续参数被识别为命令行选项。但由于file前面没有破折号,似乎没有理由将其识别为命令行选项。

答案1

第一个非选项参数sh变为$0。当sh在脚本上调用 时,这就是脚本的路径。当您运行时sh -c SOMECOMMAND,除了放入 中之外,shell 不会使用该参数进行任何操作$0。按照惯例,它是传递给 的脚本的名称-c,类似于其中是脚本的名称或路径的sh /path/to/script情况。$0

与大多数命令不同,--它被视为普通参数,而不是特殊用途的标记。所以它确实--被用作$0而不是下一个参数。

$ sh -c 'echo $1' hello            

$ sh -c 'echo $0' hello
hello
$ sh -c 'echo $0; echo $1' hello world
hello
world
$ sh -c 'echo $0; echo $1' -- hello
--
hello

这与 无关xargs,它将所有参数传递shsh命令。

答案2

在上面的示例中,--充当sh -c 'echo $(basename $1) '和之间的阻止者file。它强制字符串file作为$1的参数sh

上面的内容可以简化为:

$ find . -name "*.txt" | xargs -Ifile sh -c 'echo $(basename file) '

相关内容