-x
results in xargs
exiting as soon as it processes an argument which doesn’t fit, without trying to use any of the arguments in the line it’s currently building.
You can see the difference it makes with the following command:
(printf '%s ' {1..2048}; printf %s {1..1024}) | xargs -s 2048
Here, xargs
receives the integers from 1 to 2048, each followed by a space, then all the integers from 1 to 1024 with no separator. It runs echo
to output the arguments, sticking to a 2048-character limit. When it reads the last argument, which can’t fit in a line, xargs
outputs the “argument line too long” error but still calls echo
with the arguments it accumulated before it encountered the last argument, so you still see all integers from 1 to 2048.
With -x
:
(printf '%s ' {1..2048}; printf %s {1..1024}) | xargs -s 2048 -x
stops at 1854, because xargs
comes across the long argument, it is building the argument line starting with 1855, and because of the -x
option, it doesn’t try to do anything with the argument line it’s currently building.
I don’t think it’s possible for xargs
to run a command successfully without -x
and not with -x
. The -x
argument only ensures that, if one argument line is going to end up being too long, no part of it is processed at all.
With or without -x
, xargs
doesn’t process arguments following the overflowing argument.
(Thanks to ilkkachu for pointing out that my previous version of this answer was wrong.)
-x
apply only when the next available single argument has a length more than that specified by -s or the OS limit? – Tim Nov 24 '18 at 16:16preceding
.echo preceding
is run beforeseq 1 1024
, and with -x, without runningecho preceding
and thus without runningseq 1 1024
, how can xargs know in advance if any result in an argument line exceeds the size limit? I guess I am not clear in which order the commands on both sides of a pipe and the commands inside parentheses are executed. – Tim Nov 24 '18 at 16:31