xargsがサブシェルに渡されるときに最初の引数をスキップするのはなぜですか?


8

xargsワンライナーで複数のコマンドを呼び出す方法を探していたところ、findutilsで次のようにxargsからシェルを呼び出すように推奨されています

$ 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

シェルまたはxargsバージョンに何か問題がありますか?そのドキュメントは不正確ですか?

使用xargsの(GNU用のfindutils)4.4.2GNUのbashのバージョン4.3.11(1)-release

回答:


13

[bash]のマニュアルページには、「- -c stringcオプションが指定されている場合、コマンドは文字列から読み取られます。文字列の後に引数がある場合、それらは$ 0から始まる定位置パラメーターに割り当てられます。」-キーは$ 0です。 ; これは、コマンド名が最初の引数であることを意味します。

seq 10 | xargs sh -c 'echo $@; echo $0' sh
1 2 3 4 5 6 7 8 9 10
sh

ああなるほど!だから、ドキュメントmoveの例の最後にそれを置いています!もっと注意深く読むべきだった...ありがとう!=)
エリアス、2015年

11

xargsがサブシェルに渡されるときに最初の引数をスキップするのはなぜですか?

そうではありません。Bashは最初の引数を$ 0に割り当てます。

$ seq 10 | xargs -n2 bash -c 'echo $0'
1
3
5
7
9

$@$1 $2 $3...に展開されます。そのため、の値$0はに含まれません$@


この説明は@Janisの説明よりもはるかに明確ですが、Janisの回答には問題の適切な解決策が含まれています。
アレクシス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.