What is the equivalent to xargs -r under OsX
There is no standard way to determine if the xargs you are running is GNU or not. I set $gnuargs
to either "true" or "false" and then have a function that replaces xargs and does the right thing.
On Linux, FreeBSD and MacOS this script works for me. The POSIX standard for xargs mandates that the command be executed once, even if there are no arguments. FreeBSD and MacOS X violate this rule, thus don't need "-r". GNU finds it annoying, and adds -r
. This script does the right thing and can be enhanced if you find a version of Unix that does it some other way.
#!/bin/bash
gnuxargs=$(xargs --version 2>&1 |grep -s GNU >/dev/null && echo true || echo false)
function portable_xargs_r() {
if $gnuxargs ; then
cat - | xargs -r "$@"
else
cat - | xargs "$@"
fi
}
echo 'this' > foo
echo '=== Expect one line'
portable_xargs_r <foo echo "content: "
echo '=== DONE.'
cat </dev/null > foo
echo '=== Expect zero lines'
portable_xargs_r <foo echo "content: "
echo '=== DONE.'
The POSIX standard for xargs
mandates that the command be executed once, even if there are no arguments. This is a nuisance, which is why GNU xargs
has the -r
option. Unfortunately, neither BSD (MacOS X) nor the other mainstream Unix versions (AIX, HP-UX, Solaris) support it.
If it is crucial to you, obtain and install GNU xargs
somewhere that your environment will find it, without affecting the system (so don't replace /usr/bin/xargs
unless you're a braver man than I am — but /usr/local/bin/xargs
might be OK, or $HOME/bin/xargs
, or …).
You can use test
or [
:
if [ -s test ] ; then cat test | xargs echo content: ; fi
Here's a quick and dirty xargs-r
using a temporary file.
#!/bin/sh
t=$(mktemp -t xargsrXXXXXXXXX) || exit
trap 'rm -f $t' EXIT HUP INT TERM
cat >"$t"
test -s "$t" || exit
exec xargs "$@" <"$t"