13

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

1
  • 1
    Please edit your question and show the script.
    – Bodo
    Commented Nov 22, 2020 at 17:05

1 Answer 1

24

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.

3
  • Could you clarify, why unset?
    – Rolf
    Commented Sep 1, 2023 at 6:25
  • 2
    @Rolf At the start of the code? If I don't unset those variables, they will be inherited from the calling environment. So if the user had set the environment variable host, port or user outside of the script, and then run the script without specifying the necessary options, we would not detect that. The point of the exercise was to detect a missing -h or -u option. If you are happy to pick initial values for those variables from the environment, then remove the unset calls.
    – Kusalananda
    Commented Sep 1, 2023 at 6:28
  • Thanks that's what I thought, just wanted to make sure.
    – Rolf
    Commented Sep 1, 2023 at 13:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .