Michael
Michael

Reputation: 42050

Passing command line options to invoked script in bash

Suppose I have a script a.sh to be invoked with options

a.sh -a1 a1option -a2 a2option

Suppose also I have a script b.sh, which invokes a.sh and uses its own options. So user executes the scripts as follows:

b.sh -b1 b1option -b2 b2option -a1 a1option -a2 a2option

Now I wonder how to parse the command line options in b.sh.

I do not need to parse the entire command line. I do not want b.sh to be aware of options a1 and a2. I would like to get only options b1 and b2 and pass the rest to a.sh.

How would you do it ?

Upvotes: 3

Views: 8046

Answers (3)

dangenet
dangenet

Reputation: 265

As requested, this method avoids parsing the entire command line. Only the arguments up to -- are collected for b.sh. Then the arguments for b are stripped and only the remaining arguments are passed to a.sh.

b.sh is invoked with b.sh -b b1option -B b2option -- -a1 a1option -a2 a2option. In this line, the double dash -- indicates the end of options for b.sh. The following parses the options before the -- for use by b.sh, then removes the b arguments from the $@ so you can pass it to a.sh without worrying about what errors a.sh might give you.

while getopts ":b:B:" opt; do
    case $opt in
        b) B1=${OPTARG}
        ;;
        B) B2=${OPTARG}
        ;;
    esac 
done
## strips off the b options (which must be placed before the --)
shift $(({OPTIND}-1))
a.sh "$@"

A note: This method utilizes the bash builtin getopts. Getopts (as opposed to getopt, no s) takes only single-character options; hence, I have used b and B instead of b1 and b2.

My favorite getopts reference.

Upvotes: 6

konsolebox
konsolebox

Reputation: 75458

You can do something like this:

#!/bin/bash

while [[ $# -gt 0 ]]; do
    case "$1" in
    -b1)
        B1=true
        B1OPT=$2
        shift
        ;;
    -b2)
        B2=true
        B2OPT=$2
        shift
        ;;
    --)
        shift
        break
        ;;
    *)
        echo "Invalid option: $1"
        exit 1  ## Could be optional.
        ;;
    esac
    shift
done

bash a2.sh "$@"

Note that you should place your variable $@ inside doublequotes to prevent word splitting when expanded.

Upvotes: 4

danadam
danadam

Reputation: 3450

If a.sh can ignore options it doesn't know you can just call it with all the options b.sh was called:

a.sh "${@}"

Upvotes: 2

Related Questions