Pourquoi xargs ignore-t-il le premier argument lors du passage en sous-shell?


8

À la recherche d'un moyen d'invoquer plusieurs commandes dans une ligne unique xargs, j'ai trouvé la recommandation dans findutils pour invoquer le shell à partir de xargs comme ceci:

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

Ce qui est drôle, c'est que si j'utilise des xargs comme ça, pour une raison quelconque, cela saute le premier argument:

$ 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

Quelque chose ne va pas avec ma version shell ou xargs? Cette documentation est-elle inexacte?

Utilisation de xargs (GNU findutils) 4.4.2 et GNU bash, version 4.3.11 (1) -release .

Réponses:


13

La page de manuel [bash] indique: " -c stringSi l'option -c est présente, les commandes sont lues à partir de la chaîne. S'il y a des arguments après la chaîne, ils sont affectés aux paramètres positionnels, en commençant par $ 0. " - La clé est $ 0 ; cela signifie que le nom de la commande doit être le premier argument.

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

Oh je vois! c'est pourquoi les docs mettent ça moveà la fin dans l'exemple! J'aurais dû lire plus attentivement ... Merci! =)
elias

11

Pourquoi xargs ignore-t-il le premier argument lors du passage en sous-shell?

Ce n'est pas le cas. Bash assigne le premier argument à $ 0:

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

$@s'étend à $1 $2 $3.... Par conséquent, la valeur de $0n'est pas incluse dans $@.


Cette explication est beaucoup plus claire que celle de @ Janis, mais la réponse de Janis comprend une bonne solution au problème.
alexis
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.