0

I am trying to play around with getopt options. I want both short options and long options.

For my following test script, it does not produce my required output.

#!/bin/bash
 
options=$(getopt -o d:f:t: -l domain -l from -l to -- "$@")
[ $? -eq 0 ] || { 
    echo "Incorrect options provided"
    exit 1
}
eval set -- "$options"
while true; do
    case "$1" in
    -d | --domain)
        DOMAIN=$2;
        shift 2
        ;;
    -f | --from)
        FROM=$2;
        shift 2
        ;;
    -t | --to)
        TO=$2;
        shift 2
        ;;
    --)
        shift
        break
        ;;
    esac
    shift
done

echo "Domain is $DOMAIN"
echo "From address is $FROM"
echo "To address is $TO"
exit 0;

When I try to run it, nothing happens, it just hangs:

# bash getopt_check.sh -d hello.com  -f from@test.com -t to@test.com

Expecting output:

Domain is hello.com
From address is from@test.com
To address is to@test.com
vjwilson
  • 754
  • 2
  • 14
  • 30
  • Running your script with `bash -x` reveals that `getopt` silently removes the `--` in Bash 5.x. On Bash 3.x, it works exactly as you had hoped. Voting to close as lacking trivial debugging effort. – tripleee May 04 '21 at 06:10
  • As an aside, shell scripts should usually not have an extension at all; and if you use `.sh`, it implies that your script targets POSIX `sh`, not Bash. – tripleee May 04 '21 at 06:11
  • 1
    `it does not produce my required output.` what is the required output? – KamilCuk May 04 '21 at 06:21
  • @KamilCuk : thanks for jumping in, I edited the question. – vjwilson May 04 '21 at 06:24

1 Answers1

3

You are shifting 3 values per option, -d hello.com are 2 positions, not three.

-d | --domain)
    ...
    shift 2
    ...
-f | --from)
    ...
    shift 2
    ...
-t | --to)
    ...
    shift 2
    ...
shift             # shift 2 + shift = shift 3!

change it to:

-d|--domain)
    shift
    ...
-f|--from)
    shift
    ...
-t|--to)
    shift
    ...
shift

Prefer to use lower case variables in your script - use upper case for exported variables. Check your script with http://shellcheck.net . Prefer not to use $?, instead check the command in if like if ! options=$(getopt ...); then echo "Incorrect....

while true; do is unsafe, in case you do not handle some option it will endlessly loop. Do while (($#)); do and handle that *) echo "Internal error - I forgot to add case for my option" >&2; exit 1; ;; in the case statement.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111