Bash - Optional argument with spaces
12:48 13 Mar 2018

I have a bash script and I want to use it to pass an optional parameter with spaces to another script. My script (pass_optional_arg.sh) looks like:

#!/usr/bin/env bash

mandatory_arg=${1}

if [[ -z ${mandatory_arg} ]]
then
  echo "Mandatory arg missing"
  exit 1
fi

optional_arg=${2}

./echo_args.sh ${mandatory_arg} an_irrelevant_arg  "${optional_arg}"

Script echo_args.sh just prints the arguments in single quotes, as well as their number:

#!/usr/bin/env bash

echo "Number of args: ${#}"
for var in "${@}"
do
    echo "Arg: '"${var}"'"
done

Output of running ./pass_optional_arg.sh a_mandatory_arg 'an arg with spaces'

Number of args: 3

Arg: 'a_mandatory_arg'

Arg: 'an_irrelevant_arg'

Arg: 'an arg with spaces'

Which is exactly what I want. However, if I run without providing the optional argument: ./pass_optional_arg.sh a_mandatory_arg

Number of args: 3

Arg: 'a_mandatory_arg'

Arg: 'an_irrelevant_arg'

Arg: ''

In this case I want the arguments to be 2, and not an empty arg at the end.

If I change the last line of pass_optional_arg.sh to remove the quotes from the optional arg ./echo_args.sh ${mandatory_arg} an_irrelevant_arg ${optional_arg}

then the second case is fixed but the first breaks: ./pass_optional_arg.sh a_mandatory_arg 'an arg with spaces'

Number of args: 6

Arg: 'a_mandatory_arg'

Arg: 'an_irrelevant_arg'

Arg: 'an'

Arg: 'arg'

Arg: 'with'

Arg: 'spaces'

Of course, I could satisfy both cases with an if statement

if [[ -z ${optional_arg} ]]
then
  ./echo_args.sh ${mandatory_arg} an_irrelevant_arg
else
  ./echo_args.sh ${mandatory_arg} an_irrelevant_arg  "${optional_arg}"
fi

This may be fine for a small command like this, but cannot scale for several optional arguments. Also for a command that is very complicated and long, having to duplicate it like this is not ideal. Any way to make this work without the above if statement?

I found several questions about optional parameters OR parameters with spaces, like this, this and this, but I could not find what I am asking for in any of them.

bash shell command-line-arguments