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
(As this does not answer the question, this is should have been a comment, but is too long - so treat it as a comment).
As an alternative to FreeBSD's xargs you can use GNU Parallel which does not have this limitation. It even supports repeating the context:
seq 10 | parallel -Xj1 echo con{}text
seq 10 | parallel -mj1 echo con{}text
GNU Parallel is a general parallelizer and makes is easy to run jobs in parallel on the same machine or on multiple machines you have ssh access to. It can often replace a for
loop.
If you have 32 different jobs you want to run on 4 CPUs, a straight forward way to parallelize is to run 8 jobs on each CPU:
GNU Parallel instead spawns a new process when one finishes - keeping the CPUs active and thus saving time:
Installation
If GNU Parallel is not packaged for your distribution, you can do a personal installation, which does not require root access. It can be done in 10 seconds by doing this:
(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash
For other installation options see http://git.savannah.gnu.org/cgit/parallel.git/tree/README
Learn more
See more examples: http://www.gnu.org/software/parallel/man.html
Watch the intro videos: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
Walk through the tutorial: http://www.gnu.org/software/parallel/parallel_tutorial.html
Sign up for the email list to get support: https://lists.gnu.org/mailman/listinfo/parallel
Best Answer
When options given to xargs conflict, order may matter.
IEEE Std 1003.1-2008, 2016 Edition/Open Group Base Specifications Issue 7 added the following text1 to the specification of xargs:
This codifies the behavior of many implementations of xargs, going back to the original version in PWB/Unix, whose man page says
In the GNU version of xargs,
-L
disables any previous-I
option. So in your second example,{}
is just an ordinary argument passed toecho
, with no substitution being done.[1]Compared to IEEE Std 1003.1, 2004 Edition/Open Group Base Specifications Issue 6.