There is no standard way to determine if the xargs you are working on are GNU or not. I set $gnuargs both true and false, and then 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 requires that a command be executed once, even if there are no arguments. FreeBSD and MacOS X violate this rule, so no -r is needed. GNU finds this annoying and adds -r . This script does the right thing and can be improved if you find a version of Unix that does it differently.
#!/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' cat foo | portable_xargs_r echo "content: " echo '=== DONE.' cat </dev/null > foo echo '=== Expect zero lines' cat foo | portable_xargs_r echo "content: " echo '=== DONE.'
source share