Dear POSIX,
Why did you decide that xargs
with no filename arguments should run the command once? I can only assume that there are zero mathematicians and zero computer scientists on the relevant committee. How else could such a demented special case get through?
I used to think that as well (though I'm not sure Posix are necessarily at fault: possibly they just codified what was already a de facto standard).
Then I encountered a situation where I did need the command to run once, even with no arguments. In normal circumstances* the command runs exactly once regardless of the number of arguments, not once per argument, so there's consistency in making this always be once, even with no arguments.
Whichever way they picked was going to be wrong sometimes. What they really should've done was spec an option for picking the ‘other’ behaviour. I'm still inclined to think they picked the wrong default, but so long as I could get both I'm not that bothered.
Gnu's xargs
has the -r
option, which does what you want. FreeBSD's (and therefore presumably OS X's) doesn't have this option.**
Frustratingly I can't now recall the circumstances in which I wanted the ‘run once anyway’ behaviour; if I remember I'll post a follow-up, since I realize this is much less persuasive without it!
* Non-normal circumstances include having so much input it needs to be split into multiple invocations of the command, or using -n 1
to run the command once per argument.
** FreeBSD's does however have the useful -o
option, handy for opening a bunch of files in Vim, which Gnu's is missing.
Most shells will invoke foo
and pass a literal bar.*
as the first argument if you run foo bar.*
if nothing in the current directory matches bar.*
. In bash since 2.something you can shopt -s failglob
to prevent this.
But then the shell will also refuse to let you run foo bar.* baz.*
if either bar.*
or baz.*
fail, when really you probably only wanted it to refuse if both fail. So basically you want the behaviour of shopt -s nullglob
when there’s more than one glob.
Or at least, you want that behaviour most of the time.
Defaults: It’s Tricky To Get Them Right.
There's another reply to this journal entry over here.