Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use long options with the Bash getopts builtin?

I am trying to parse a -temp option with Bash getopts. I'm calling my script like this:

./myscript -temp /foo/bar/someFile

Here is the code I'm using to parse the options.

while getopts "temp:shots:o:" option; do
    case $option in
        temp) TMPDIR="$OPTARG" ;;
        shots) NUMSHOTS="$OPTARG" ;;
        o) OUTFILE="$OPTARG" ;;
        *) usage ;;
    esac
done
shift $(($OPTIND - 1))

[ $# -lt 1 ] && usage
like image 250
Hemang Avatar asked Aug 18 '12 22:08

Hemang


People also ask

What does getopts do in Bash?

On Unix-like operating systems, getopts is a builtin command of the Bash shell. It parses command options and arguments, such as those passed to a shell script.

Which is better getopt or getopts?

I know that getopts would be the preferred way in terms of portability but AFAIK it doesn't support long options. getopt supports long options but the BashGuide recommends strongly against it: Never use getopt(1). getopt cannot handle empty arguments strings, or arguments with embedded whitespace.

How do I add options in Bash?

The ability to process options entered at the command line can be added to the Bash script using the while command in conjunction with the getops and case commands. The getops command reads any and all options specified at the command line and creates a list of those options.

How do I use getopts in Linux?

To tell getopts that an option will be followed by an argument, put a colon ” : ” immediately behind the option letter in the options string. If we follow the “b” and “c” in our options string with colons, getopt will expect arguments for these options.


3 Answers

As other people explained, getopts doesn't parse long options. You can use getopt, but it's not portable (and it is broken on some platform...)

As a workaround, you can implement a shell loop. Here an example that transforms long options to short ones before using the standard getopts command (it's simpler in my opinion):

# Transform long options to short ones
for arg in "$@"; do
  shift
  case "$arg" in
    '--help')   set -- "$@" '-h'   ;;
    '--number') set -- "$@" '-n'   ;;
    '--rest')   set -- "$@" '-r'   ;;
    '--ws')     set -- "$@" '-w'   ;;
    *)          set -- "$@" "$arg" ;;
  esac
done

# Default behavior
number=0; rest=false; ws=false

# Parse short options
OPTIND=1
while getopts "hn:rw" opt
do
  case "$opt" in
    'h') print_usage; exit 0 ;;
    'n') number=$OPTARG ;;
    'r') rest=true ;;
    'w') ws=true ;;
    '?') print_usage >&2; exit 1 ;;
  esac
done
shift $(expr $OPTIND - 1) # remove options from positional parameters
like image 75
mcoolive Avatar answered Sep 25 '22 21:09

mcoolive


getopts can only parse short options.

Most systems also have an external getopt command, but getopt is not standard, and is generally broken by design as it can't handle all arguments safely (arguments with whitespace and empty arguments), only GNU getopt can handle them safely, but only if you use it in a GNU-specific way.

The easier choice is to use neither, just iterate the script's arguments with a while-loop and do the parsing yourself.

See http://mywiki.wooledge.org/BashFAQ/035 for an example.

like image 32
geirha Avatar answered Sep 22 '22 21:09

geirha


getopts is used by shell procedures to parse positional parameters of 1 character only (no GNU-style long options (--myoption) or XF86-style long options (-myoption))

like image 43
Stephane Rouberol Avatar answered Sep 22 '22 21:09

Stephane Rouberol