1

Each long option name in longopts may be followed by one colon to indicate it has a required argument, and by two colons to indicate it has an optional argument.

in man bash.

I wrote a bash function optionarg:

optionarg (){
    opts=$(getopt -o , --long name:,pass:: -- "$@")
    eval set -- "$opts"
    while true; do
        case "$1" in
            --name)
                name=$2
                echo  "name is " $name
                shift 2;;
            --pass)
                case "$2" in 
                    '')
                        echo "no pass argument"
                        shift 2;; 
                    *)
                        pass=$2
                        echo  "pass" $pass
                        shift 2;;
                esac;;               
            --)
                shift 1;;
            *)  break;;
        esac
    done }

Let test my optionarg here.
1.Assign no argument with pass.

optionarg --name tom --pass
name is  tom
no pass argument

2.Assign an argument xxxx with pass.

optionarg --name tom --pass xxxx
name is  tom
no pass argument

How to fix my optionarg function to get such output?

optionarg --name tom --pass xxxx
name is  tom
pass xxxx
showkey
  • 482
  • 42
  • 140
  • 295
  • See also [Using getopts to process long and short command line options](https://stackoverflow.com/q/402377/519360), including [my answer](https://stackoverflow.com/a/28466267/519360), which can accept long options with optional arguments and which doesn't require the external call to `getopt`. – Adam Katz Feb 10 '20 at 15:59

2 Answers2

3

Long options use = to assign an optional value:

$ optionarg --name tom --pass=xxxx
name is  tom
pass xxxx

This is documented in man getopt:

If the option has an optional argument, it must be written directly after the long option name, separated by =, if present (if you add the = but nothing behind it, it is interpreted as if no argument was present; this is a slight bug, see the BUGS).

choroba
  • 231,213
  • 25
  • 204
  • 289
1

Personally i would do it with only case

optionarg () {
    while [[ $@ ]]; do
        case "$1" in
            --name|-n) name=$2;;
            --pass|-p) pass=$2;;
        esac               
        shift
    done
    echo "name=$name"
    echo "pass=$pass"
}

Usage

$ optionarg --name user --pass dfgd
name=user
pass=dfgd

$ optionarg -n user -p dfgd
name=user
pass=dfgd
Ivan
  • 6,188
  • 1
  • 16
  • 23