1

xargs has an option -x which specifies that xargs exits if the size (see the -s option) is exceeded.

Does that mean that xargs either executes all the arguments at once (if the number of characters in the command line does not exceed the number specified by -s) or doesn't execute at all (otherwise)?

Is it correct that with -x, xargs never executes a proper (mearning: not all) subset of arguments where the command line length does not exceed the number specified by -s?

Tim
  • 101,790

1 Answers1

3

-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.)

Stephen Kitt
  • 434,908
  • Does -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:16
  • when will it happen that xargs can run a command successfully without -x but fails with -x? Is it when -s is used to specify a limit small enough to disallow the next group of arguments in a command, without reaching the OS limit? – Tim Nov 24 '18 at 16:21
  • In the last two commands, the only difference between their outputs is with -x, it doesn't have a line preceding. echo preceding is run before seq 1 1024, and with -x, without running echo preceding and thus without running seq 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
  • How does xargs know when a stdin input ends, so that it can start processing it? – Tim Nov 24 '18 at 22:38
  • https://unix.stackexchange.com/questions/483939/how-does-xargs-know-when-a-stdin-input-ends-so-that-it-can-start-processing-it – Tim Nov 24 '18 at 22:51
  • Another option "-n max-args: Use at most max-args arguments per command line. Fewer than max-args arguments will be used if the size (see the ‘-s’ option) is exceeded, unless the ‘-x’ option is given, in which case xargs will exit." What does -x mean here? Does it mean the same as what you explained? Is -x only used when -n is used? – Tim Nov 25 '18 at 05:53
  • "The -x argument only ensures that, if one argument line is going to end up being too long, no argument line is processed at all." -- hmm no, at least GNU xargs and the one that comes with Macs happily run any initial commands until there is an issue – ilkkachu Nov 25 '18 at 11:17
  • Thanks @ilkkachu, I finally got round to reading the source code and my answer was wrong. – Stephen Kitt Nov 25 '18 at 22:04