Search code examples
linuxbashgetoptgetopts

about getopt syntax error


Alright, I am a linux bash amateur playing with getops and getop; I have read several conversations in several forums regarding the topic, but I can't seem to make my code work.

Here is a little script using getopts, recycled from this forum:

#!bin/bash

while getopts ":a:p:" opt; do
  case $opt in
    a) arg_1="$OPTARG"
    ;;
    p) arg_2="$OPTARG"
    ;;
    \?)
    ;;
  esac
done

printf "Argument firstArg is %s\n" "$arg_1"
printf "Argument secondArg is %s\n" "$arg_2"

It does its job:

bash test02.sh -asomestring -bsomestring2 #either with or without quotes
#Argument firstArg is somestring
#Argument secondArg is somestring2

Now, since I want to try long options names, I am trying getopt, trying to comprehend the syntax from examples I found online:

#!/bin/bash

temp=`getopt -o a:b: -l arga:,argb:--"$@"`
eval set --"$temp"

while true ; do
  case "$1" in
    a|arga) firstArg="$OPTARG"
    ;;
    b|argb) secondArg="$OPTARG"
    ;;
    \?)
    ;;
  esac
done

printf "Argument firstArg is %s\n" "$firstArg"
printf "Argument secondArg is %s\n" "$secondArg"

The above code does not work:

bash test04.sh -a'somestring' -b'somestring2' #either with or without quotes
#getopt: invalid option -- 'b'
#Try `getopt --help' for more information.
#
bash test04.sh --arga=somestring --argb=somestring2
#getopt: unrecognized option '--argb=somestring2'
#Try `getopt --help' for more information.

Can you please help me understand my mistakes?


Solution

  • You need proper spaces before and after --.

    temp=`getopt -o a:b: -l arga:,argb: -- "$@"`
    eval set -- "$temp" 
    

    And in your while loop that processes the result, you need to use the shift command to go to the next option, otherwise you'll just keep processing the same option forever.

    getopt doesn't set variables like $OPTARG, you just use positional parameters.

    while true ; do
      case "$1" in
        -a|--arga) firstArg="$2"; shift 2
        ;;
        -b|--argb) secondArg="$2"; shift 2
        ;;
        --) shift; break
        ;;
        *) echo "Bad option: $1"; shift
        ;;
      esac
    done
    

    See the examples at https://www.tutorialspoint.com/unix_commands/getopt.htm