Ahmad Shah
Ahmad Shah

Reputation: 321

How to use getopt with long options in Bash?

I have the following code in Bash:

declare {BPM_USERNAME,BPM_PASSWORD,HOST,TARGET_IP,OVERRIDE_STATUS}=''
OPTS=`getopt -a --longoptions username:,password:,csc:,ip:,override: -n "$0" -- "$@"`
eval set -- "$OPTS"

if [ $? != 0 ] ; then echo "Failed parsing options." >&2 ; exit 1 ; fi

while true; do
    echo ""
    echo $OPTS
    echo $1
    echo $2

  case "$1" in
    --username )
        BPM_USERNAME=$2
        shift 2
        ;;
    --password )
        BPM_PASSWORD=$2
        shift 2
        ;;
    --csc )
        HOST=$2
        shift 2
        ;;
    --ip )
        TARGET_IP=$2
        shift 2
        ;;
    --override )
        OVERRIDE_STATUS=$2
        shift 2
        ;;
    --)
        shift
        echo "Breaking While loop"
        break
        ;;
    *)
        echo ""
        echo "Error in given Parameters. Undefined: "
        echo $*
        echo ""
        echo "Usage: $0 [--username BPM_USERNAME] [--password BPM_PASSWORD] [--ip IP ADDRESS_OF_VyOS/BPM] [--csc CLIENT_SHORT_CODE] [--override TRUE/FALSE]"
        exit 1
  esac
done

I give Bash the following command (name of script is UpdateSSL.sh):

./UpdateSSL.sh -username bpmadmin -password bpmadmin -ip 10.91.201.99 -csc xyz -override False

But instead of parsing the options, I get back the following result (showing that the while loop goes to the *) case):

'bpmadmin' --password 'bpmadmin' --ip '10.91.201.99' --csc 'xyz' --override 'False' --
bpmadmin
--password

Error in given Parameters. Undefined: 
bpmadmin --password bpmadmin --ip 10.91.201.99 --csc xyz --override False --

Usage: ./UpdateSSL.sh [--username BPM_USERNAME] [--password BPM_PASSWORD] [--ip IP ADDRESS_OF_VyOS/BPM] [--csc CLIENT_SHORT_CODE] [--override TRUE/FALSE]

I don't know what I'm doing wrong.

Upvotes: 4

Views: 11038

Answers (1)

cxw
cxw

Reputation: 17031

The answer is actually at the very end of the man page:

The syntax if you do not want any short option variables at all is not very intuitive (you have to set them explicitly to the empty string).

In order to make getopt run with no short options, you have to manually specify -o '' as the first argument. I made some other changes, and the below works on my system (see *** markers):

#!/bin/bash

# *** Make sure you have a new enough getopt to handle long options (see the man page)
getopt -T &>/dev/null
if [[ $? -ne 4 ]]; then echo "Getopt is too old!" >&2 ; exit 1 ; fi

declare {BPM_USERNAME,BPM_PASSWORD,HOST,TARGET_IP,OVERRIDE_STATUS}=''
OPTS=$(getopt -o '' -a --longoptions 'username:,password:,csc:,ip:,override:' -n "$0" -- "$@")
    # *** Added -o '' ; surrounted the longoptions by ''
if [[ $? -ne 0 ]] ; then echo "Failed parsing options." >&2 ; exit 1 ; fi
    # *** This has to be right after the OPTS= assignment or $? will be overwritten

set -- $OPTS
    # *** As suggested by chepner

while true; do
    # ... no changes in the while loop
done

Upvotes: 7

Related Questions