Por que os xargs ignoram o primeiro argumento ao passar para o subshell?

8

Procurando uma maneira de invocar mais de um comando em um xargs one-liner, eu encontrei a recomendação em findutils para invocar o shell de xargs assim:

$ find ... | xargs sh -c 'command $@'

O engraçado é que, se eu uso xargs assim, por algum motivo, ele pula o primeiro argumento:

$ 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

Há algo errado com minha versão shell ou xargs? Essa documentação é imprecisa?

Usando xargs (GNU findutils) 4.4.2 e GNU bash, versão 4.3.11 (1) -release .

    
por elias 28.05.2015 / 05:02

2 respostas

12

A página man [bash] diz: " -c string Se a opção -c estiver presente, então os comandos serão lidos da string. Se houver argumentos após a string, eles serão atribuídos aos parâmetros posicionais, começando com $ 0. "- A chave é $ 0 ; isso significa que o nome do comando será o primeiro argumento.

seq 10 | xargs sh -c 'echo $@; echo $0' sh
1 2 3 4 5 6 7 8 9 10
sh
    
por 28.05.2015 / 05:07
10

Why does xargs skip first argument when passing to subshell?

Isso não acontece. Bash atribui o primeiro argumento a $ 0:

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

$@ expande para $1 $2 $3 .... Consequentemente, o valor de $0 não está incluído em $@ .

    
por 28.05.2015 / 05:07

Tags