# Why does xargs skip first argument when passing to subshell?

Looking for a way to invoke more than one command in a xargs one-liner, I found the recommendation in findutils to invoke the shell from xargs like this:

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


The funny thing is, if I use xargs like that, for some reason it skips the first 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


Is something wrong with my shell or xargs version? Is that documentation inaccurate?

Using xargs (GNU findutils) 4.4.2 and GNU bash, version 4.3.11(1)-release.

The [bash] man page says: "-c string If the -c option is present, then commands are read from string. If there are arguments after the string, they are assigned to the positional parameters, starting with $0." - The key is$0; it means that the command name shall be the first argument.

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

• oh, I see! so that's why the docs put that move at the end in the example! I should've read more carefully... Thank you! =) – elias May 28 '15 at 3:14

Why does xargs skip first argument when passing to subshell?

It doesn't. Bash assigns the first argument to $0: $ seq 10 | xargs -n2 bash -c 'echo $0' 1 3 5 7 9  $@ expands to $1 $2 $3 .... Consequently, the value of $0 is not included in \$@.

• This explanation is much clearer than @Janis's, but Janis's answer includes a good solution to the problem. – alexis May 28 '15 at 12:57