Perché xargs salta il primo argomento quando passa a subshell?


8

Alla ricerca di un modo per invocare più di un comando in un one-liner di xargs, ho trovato la raccomandazione in findutils di invocare la shell da xargs in questo modo:

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

La cosa divertente è che, se uso xargs in questo modo, per qualche motivo salta il primo argomento:

$ 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

C'è qualcosa che non va nella mia versione shell o xargs? Tale documentazione è inesatta?

Usando xargs (GNU findutils) 4.4.2 e GNU bash, versione 4.3.11 (1)-release .

Risposte:


13

La pagina man [bash] dice: " -c stringSe è presente l'opzione -c, i comandi vengono letti dalla stringa. Se ci sono argomenti dopo la stringa, vengono assegnati ai parametri posizionali, a partire da $ 0. " - La chiave è $ 0. ; significa che il nome del comando deve essere il primo argomento.

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

Oh, capisco! quindi è per questo che i documenti lo hanno messo movealla fine nell'esempio! Avrei dovuto leggere più attentamente ... Grazie! =)
elias,

11

Perché xargs salta il primo argomento quando passa a subshell?

Non Bash assegna il primo argomento a $ 0:

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

$@si espande in $1 $2 $3.... Di conseguenza, il valore di $0non è incluso in $@.


Questa spiegazione è molto più chiara di quella di @ Janis, ma la risposta di Janis include una buona soluzione al problema.
alexis,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.