Bash menu with multiple parameters in one row

bashscriptingshell-script

I have searched a couple of days and still didn't found the answer. I hope that you can point me in right direction.

I would like to know how to write a bash script with a options, that can be
called in one row, such as: script.sh -a -b -c. Parameters which aren't chosen are ignored.

Menu/options should be like:

-a description: something
-b description: something else
-c description: something different
-d description: something..

is there any way to do this?

Best Answer

The usual way of handling switches and arguments is with the getopts function. In bash this is a builtin and you can find information about it in the bash man page (man bash).

Essentially, you declare a string that tells getopts what parameters to expect, and whether they should have an argument. It's getopts that handles bunched parameters (eg -abc being equivalent to -a -b -c) and the parsing of the command line. At the end of the getopts processing you have the remainder of the command line to handle as you see fit.

A typical script segment could look something like this

ARG_A= FLAG_B= FLAG_C=
while getopts 'a:bc' OPT    # -a {argument}, -b, -c
do
    case "$OPT" in
        a)    ARG_A="$OPTARG" ;;
        b)    FLAG_B=yes ;;
        c)    FLAG_C=yes ;;
        *)    echo "ERROR: the options are -a {arg}, -b, -c" >&2; exit 1 ;;
    esac
done
shift $(($OPTIND - 1))

echo "Remaining command line: $*"

You can add ? as a command option if you want a nice usage message. Remember that in the case block you would need to quote it or prefix it with a backslash so it's treated as a literal.

If you're wanting to run this under a different shell that doesn't have the builtin, or if you want to use long arguments such as --verbose instead of just -v take a look at the getopt utility. This is not a builtin but has been written to deliver in the more sophisticated situation.