Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pass optional parameters to another command within a bash script?

Tags:

bash

shell

I am writing a bash script that takes in some optional parameters. I want to translate them and pass them to another script. However, I'm having a hard time passing the optional parameters gracefully.

Here's a outline of what I managed to get working in pseudocode:

a.sh:

if arg1 in arguments; then
    firstArg="first argument"
fi
if arg2 in arguments; then
    secondArg="second argument"
fi

./b.sh $firstArg $secondArg "default argument"

Note the spaces in the arguments.

b.sh:

for arg in "$@"
do
    echo $arg
done

I want to call b.sh, optionally with firstArg and secondArg and a default argument like so:

./b.sh $firstArg $secondArg "default argument"

The problem with this is that if $firstArg or $secondArg are strings with spaces, they will be represented as multiple arguments, and the output will be something like:

first
argument
second
argument
default argument

Okay, that's easy to fix, let's capture the entire string of the arguments by adding quotes around it like so:

./b.sh "$firstArg" "$secondArg" "defaultArg"

Problem is if, for example, firstArg is not set, it results in a blank line (as it will interpret "" as a parameter), so the output will be something like:

(blank line here)
second argument
defaultArg

I've also tried constructing a string and passing it to the shell script, but it doesn't seem to work that way either (it interprets the whole string as an argument, even if I add separate the arguments with quotes).

Note that calling b.sh from my command line with the arguments quoted works fine. Is there a way to mimic how this works from within a bash script?

like image 853
Andrew Avatar asked May 06 '15 20:05

Andrew


People also ask

How do I pass arguments from one bash script to another?

We can use the getopts program/ command to parse the arguments passed to the script in the command line/ terminal by using loops and switch-case statements. Using getopts, we can assign the positional arguments/ parameters from the command line to the bash variables directly.

How do I add options to a bash script?

The ability to process options entered at the command line can be added to the Bash script using the while command in conjunction with the getops and case commands. The getops command reads any and all options specified at the command line and creates a list of those options.

How do you add optional parameters?

Here for the [Optional] attribute is used to specify the optional parameter. Also, it should be noted that optional parameters should always be specified at the end of the parameters. For ex − OptionalMethodWithDefaultValue(int value1 = 5, int value2) will throw exception.


1 Answers

If you literally want to copy all arguments given, but add one more:

# this works in any POSIX shell
./b.sh "$@" defaultArg

Alternately, to explicitly pass firstArg and secondArg, but only if they exist (note that set-to-an-empty-value counts as "existing" here):

# this works in any POSIX shell
./b.sh ${firstArg+"$firstArg"} ${secondArg+"$secondArg"} defaultArg

If you want to treat set-to-an-empty-value as not existing:

# this works in any POSIX shell
./b.sh ${firstArg:+"$firstArg"} ${secondArg:+"$secondArg"} defaultArg

An alternate approach is to build up an array of arguments:

# this requires bash or another shell with arrays and append syntax
# be sure any script using this starts with #!/bin/bash
b_args=( )
[[ $firstArg ]] && b_args+=( "$firstArg" )
[[ $secondArg ]] && b_args+=( "$secondArg" )
b_args+=( "default argument" )
./b.sh "${b_args[@]}"

If you want something with the same flexibility as the array method, but without the compatibility issues, define a function; within it, you can safely override "$@" without impacting the rest of the script:

runB() {
  set --
  [ -n "$firstArg" ]  && set -- "$@" "$firstArg"
  [ -n "$secondArg" ] && set -- "$@" "$secondArg"
  ./b.sh "$@" "default argument"
}
like image 148
Charles Duffy Avatar answered Nov 15 '22 10:11

Charles Duffy