我发现在寻找一种在 xargs 单行中调用多个命令的方法findutils 中建议从 xargs 调用 shell像这样:
$ find ... | xargs sh -c 'command $@'
有趣的是,如果我像这样使用 xargs,由于某种原因它会跳过第一个参数:
$ seq 10 | xargs bash -c 'echo $@'
2 3 4 5 6 7 8 9 10
$ seq 10 | xargs -n2 bash -c 'echo $@'
2
4
6
8
10
我的 shell 或 xargs 版本有问题吗?该文档不准确吗?
使用xargs(GNU findutils)4.4.2和GNU bash,版本 4.3.11(1)-发布。
答案1
[bash] 手册页显示:“-c string
如果存在 -c 选项,则从字符串中读取命令。如果字符串后面有参数,它们将被分配给位置参数,从 $0 开始。“ - 关键是$0;这意味着命令名称应为第一个参数。
seq 10 | xargs sh -c 'echo $@; echo $0' sh
1 2 3 4 5 6 7 8 9 10
sh
答案2
为什么 xargs 在传递给子 shell 时跳过第一个参数?
事实并非如此。 Bash 将第一个参数分配给 $0:
$ seq 10 | xargs -n2 bash -c 'echo $0'
1
3
5
7
9
$@
展开为$1
$2
$3
.... 因此, 的值$0
不包含在 中$@
。