Search code examples
bashshellgetopt

Using getopt to parse second argument into a variable


How do I parse the second argument into a variable using bash and getopt on the following script.

I can do sh test.sh -u and get "userENT" to display. But if I do sh test.sh -u testuser on this script I get an error.

#!/bin/sh

# Now check for arguments
OPTS=`getopt -o upbdhrstv: --long username,password,docker-build,help,version,\
  release,remote-registry,stage,develop,target: -n 'parse-options' -- "$@"`



while true; do
  case "$1" in
    -u | --username) 
            case "$2" in
               *) API_KEY_ART_USER="$2"; echo "userENT" ;shift ;;
            esac ;;
    -- ) shift; break ;;
    * ) if [ _$1 != "_" ]; then ERROR=true; echo; echo "Invalid option $1"; fi; break ;;

   esac
done
echo "user" $API_KEY_ART_USER

How can I pass the -u testuser and not have an Invalid option testuser error?

Output:

>sh test3.sh -u testuser
userENT

Invalid option testuser
user testuser

Solution

  • man getopt would tell you that a colon following the option indicates that it has an argument. You only have a colon after the v. You also weren't shifting within your loop, so you'd be unable to parse any options past the first one. And I'm not sure why you felt the need to have a second case statement that only had a single default option. In addition, there were a number of poor practices in your code including use of all caps variable names and backticks instead of $() for executing commands. And you've tagged your question but your shebang is /bin/sh. Give this a try, but you shouldn't be using code without understanding what it does.

    #!/bin/sh
    
    # Now check for arguments
    opts=$(getopt -o u:pbdhrstv: --long username:,password,docker-build,help,version,\
        release,remote-registry,stage,develop,target: -n 'parse-options' -- "$@")
    
    while true; do
        case "$1" in
        -u|--username)
            shift
            api_key_art_user="$1"
            echo "userENT"
        ;;
        --)
            shift;
            break
        ;;
        *)
            if [ -n "$1" ]; then 
                err=true
                echo "Invalid option $1"
            fi
            break
        ;;
        esac
        shift
    done
    echo "user $api_key_art_user"