2

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.

1 Answer 1

1

You'll need a conditional somewhere, because "..." is always going to be a distinct argument, even if the ... is empty. By the way, you absolutely want to quote all the parameter expansions:

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

You might want to use an array instead:

mandatory_arg=${1}

# Check $# directly; just because $1 is empty doesn't mean it is *missing*
if (( $# < 1 ))
then
  echo "Mandatory arg missing"
  exit 1
fi
# Or simply
# mandatory_arg=${1:?Mandatory arg missing}

args=( "$mandatory_arg" an_irrelevant_arg )
(( $# >= 2 )) && args+=("$2")

./echo_args.sh "${args[@]}"
Sign up to request clarification or add additional context in comments.

1 Comment

Great solution!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.