Search code examples
linuxbashgetoptgetopts

Getopts in bash script with sub-arguments


I would like to be able to run a script like this ( with sub-arguments ): I need to be able to use short and long options

./myscript.sh -u myname --delete-config --delete-data

./myscript.sh -a myname ..........................

./myscript.sh -h

Actually i have :


OPTS=`getopt -o a?d:h?dd?dc? --long apps,delete:,delete-data,delete-config -n 'parse-options' -- "$@"`

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

eval set -- "$OPTS"


while true; do
  case "$1" in
    -a | --apps ) 
        showHelp
        exit 0
        ;;
    -d | --delete ) 
        username="$2"
        echo $username
        shift 2
        echo "$1"
        echo "$2"
       
        # Here i can add argument to the command

        case "$1" in
            -dd | --delete-data ) 
                deleteData
                shift 1
                ;;
            -dc | --delete-config ) 
                deleteConfig
                shift 1
                ;;   
            * ) echo "Unexpected option: $1 - this should not happen."
                showHelp 
                break 
                ;;
        esac
        ;;
    -h | --help ) 
        showHelp 
        break 
        ;;
    -- ) shift; 
        break 
        ;;    
    * ) echo "Unexpected option: $1 - this should not happen."
        showHelp 
        break 
        ;;
  esac
done

The result of the script is :

--delete toto --delete-data --delete-config

toto

--delete-data

--delete-config

suppress en cours data

Unexpected option: --delete-config - this should not happen.

I don't understand what i'm making wrong with shift and getopts


Solution

  • Slightly different version :

    #!/usr/bin/env bash
    
    OPTS=`getopt -o a?d:h?dd?dc? --long apps,delete:,delete-data,delete-config -n 'parse-options' -- "$@"`
    
    if [ $? != 0 ] ; then echo "Failed parsing options." >&2 ; exit 1 ; fi
    
    eval set -- "$OPTS"
    
    
    while test "$1" != --; do
      case "$1" in
        -a | --apps )
            showHelp
            exit 0
            ;;
        -d | --delete )
            username="$2"
            echo $username
            shift 2
            echo "$1"
            echo "$2"
    
            # Here i can add argument to the command
    
            while test "$1" != --; do
                case "$1" in
                    -dd | --delete-data )
                        echo deleteData
                        shift 1
                        ;;
                    -dc | --delete-config )
                        echo deleteConfig
                        shift 1
                        ;;
                    * ) echo "Unexpected option: $1 - this should not happen."
                        showHelp
                        break
                        ;;
                esac
            done
            ;;
        -h | --help )
            showHelp
            break
            ;;
        -- ) shift;
            break
            ;;
        * ) echo "Unexpected option: $1 - this should not happen."
            showHelp
            break
            ;;
      esac
    done