这是有问题的命令
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
,它将所有参数传递sh
给sh
命令。
答案2
在上面的示例中,--
充当sh -c 'echo $(basename $1) '
和之间的阻止者file
。它强制字符串file
作为$1
的参数sh
。
上面的内容可以简化为:
$ find . -name "*.txt" | xargs -Ifile sh -c 'echo $(basename file) '