Bash getopts, mandatory arguments

I am working with a pretty simple bash script, but I am facing a problem which I can’t resolve:

I have myscript.sh with three parameters, -u, -h, and -p.
Both -u and -h are mandatory, needed for the script to run.

What I would like to do is, if myscript.sh -u User1 and nothing more it should terminate with exit 1.

I want my script to analyze and just run the script if myscript.sh -u User1 -h Localhost are on the options, otherwise it should exit.

Many thanks

Asked By: Learner33

||

Maybe something like this?

#!/bin/bash

unset -v host
unset -v port
unset -v user

while getopts h:p:u: opt; do
        case $opt in
                h) host=$OPTARG ;;
                p) port=$OPTARG ;;
                u) user=$OPTARG ;;
                *)
                        echo 'Error in command line parsing' >&2
                        exit 1
        esac
done

shift "$(( OPTIND - 1 ))"

if [ -z "$host" ] || [ -z "$user" ]; then
        echo 'Missing -h or -u' >&2
        exit 1
fi

# The rest of the script continues here and may make use of
# "$host" and "$user", and possibly "$port".

The main bit here is the short if statement at the end that tests whether there were ever anything assigned to the host or user variables in the while loop. If either of these variables are empty, then the code treats it as an error and exits after outputting a short diagnostic message.

The script shown above should also be able to run under /bin/sh as it does not contain any bashishms.

Instead of the if statement, you could use

: ${host:?Missing -h}
: ${user:?Missing -u}

or, even shorter,

: ${host:?Missing -h} ${user:?Missing -u}

The : command is a utility that doesn’t do anything, but its argument would still be processed by the calling shell, like for all commands. With the two lines above, the shell would try to expand the host and user variables, and if the variable is unset, or if the expansion results in an empty string, then the string to the right after ? will be outputted and the script will terminate with a non-zero exit status:

$ bash script.sh -h somehost
script.sh: line 21: user: Missing -u
$ echo $?
1

The ${variable:?text} expansion is standard and therefore supported by bash and all other POSIX sh-like shells.

Answered By: Kusalananda
Categories: Answers Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.