-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.)
-xapply 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 precedingis run beforeseq 1 1024, and with -x, without runningecho precedingand 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