Почему xargs пропускает первый аргумент при передаче в subshell?

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.2 и GNU bash, версия 4.3.11 (1) -релиз .

Элиас
источник

Ответы:

13

Страница man [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
Janis
источник
а ну понятно! вот почему moveв этом примере документы ставятся в конце! Я должен был прочитать более внимательно ... Спасибо! =)
Элиас
11

Почему xargs пропускает первый аргумент при передаче в subshell?

Это не так. Bash назначает первый аргумент $ 0:

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

$@расширяется до $1 $2 $3.... Следовательно, значение $0не входит в $@.

John1024
источник
Это объяснение намного яснее, чем у @ Janis, но ответ Janis включает в себя хорошее решение проблемы.
Алексис