I'm puzzled by what actually defines an arg in xargs.
The man page seems to suggest that args are delimited by blanks (I assume that means whitespace). However, the following script doesn't behave as I would expect. Here is an excerpt from man's DESCRIPTION section:

xargs reads items from the standard input, delimited by blanks (which can be protected with double or single quotes or a backslash) or new‐lines, and executes the command ...

It seems that perhaps xargs works in blocks of what the man-page calls items. Does this mean a null-delimited item, or a newline delimited item?

Basically, I don't understand why, in the following script, xargs treats the input as a single arg, even though the spaces (in stdin) are not protected. I expected xargs to treat stdin as 3 args, or at least reduce multiple spaces to a single space, but it does neither of these!

if [[ $1 == "." ]] ;then  # act on a recursive call to self
    shift                 # scrap the 'recursive' arg
    printf '|%s|\n' "$@"  # print all 'xargs' args
    printf '|%s|\n' "$1"  # print only the first 'xargs' arg
printf 'a    b    c\n' |xargs -I {} "$0" "." {}   

Here is the output; showing only a single arg was passed to the script.

|a    b    c|
|a    b    c|

But I would have expected 3 separate args, like this:


Read what the manual page says about option -I, which you are using:

-I replace-str

Replace occurrences of replace-str in the initial-arguments with names read from standard input. Also, unquoted blanks do not terminate input items; instead the separator is the newline character.

  • OMG! That was easy! I was looking at the wrong things... thanks ;) ... – Peter.O Jan 19 '12 at 0:11

No, this isn't about “blocks” vs “items”, that's just shifting terminology. xargs takes input quoted with ' or " and delimited by blanks, except when certain options are passed.

Some options change to line-by-line processing with no quoting: -I, -L, -i (GNU), -l (GNU). The option -0 (where available) changes to null-delimited input with no quoting. The option -d (GNU) changes to a custom delimiter with no quoting.


One of the reasons for making GNU Parallel was to make it more predictable than xargs. https://www.gnu.org/software/parallel/history.html

If you get hit by the way xargs interprets arguments, consider using GNU Parallel instead.

You can install GNU Parallel simply by:

wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel
cp parallel sem

Watch the intro videos for GNU Parallel to learn more: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

  • Please only mention Parallel when you have a useful example, otherwise it seems like spam. You have copy-pasted this into several answers today. – Mikel May 10 '12 at 3:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.