0

I have this:

r_flag=' -r ';

docker ps -aq  | xargs "$r_flag" docker rm -v | cat;

and I get this error on ubuntu:

xargs: -r : No such file or directory

why is that? I am just trying to pass the -r option to xargs. The problem seems to go a way if I change it from:

r_flag=' -r ';

to

r_flag='-r';

lame...! But why.

1

With r_flag=" -r " the spaces are included in the value of the variable. In other words, the argument "$r_flag" to xargs does not start with a -, and is therefore not taken as an option. An option's first character has to be a dash.

Since it's not an option, xargs interprets it as the name of the utility that it should run. It fails to find the utility and complains.

Alternate way of doing the right thing:

set -- -r
docker ps -aq | xargs "$@" docker rm -v

Or, using an array in bash,

xargs_opts=( -r )
docker ps -aq | xargs "${xargs_opts[@]}" docker rm -v

This would make it easy to pass additional flags to xargs without having to define new variables:

set -- -r -t
docker ps -aq | xargs "$@" docker rm -v

Or, using an array in bash,

xargs_opts=( -r -t )
docker ps -aq | xargs "${xargs_opts[@]}" docker rm -v

The array passed to the command could obviously be constructed dynamically:

xargs_opts=()

if should_trace; then
    xargs_opts+=( -t )
fi
if should_not_run_on_empty; then
    xargs_opts+=( -r )
fi
  • yeah, wonder why the whitespace is interpreted as start of variable, a way to avoid that? – Alexander Mills May 28 at 20:38
  • @AlexanderMills Not as a variable, as a non-option, an operand. Yes, you can simply avoid putting the spaces into the value of r_flag. – Kusalananda May 28 at 20:40
  • yeah the whitespaces around the flag were designed to be safe in case it's inserted like this by accident xargs"${r_flag}"docker rm -v (w/o any whitespace on one side of the var etc) – Alexander Mills May 28 at 20:41
  • 1
    @AlexanderMills I would say that that would be a programming error. If you try that command, you will see that the shell complains about not finding the xargs -r docker command (it takes that whole string as the literal name of a single command). – Kusalananda May 28 at 20:42

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.