Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

An example of how to use getopts in bash

I want to call myscript file in this way:

$ ./myscript -s 45 -p any_string 

or

$ ./myscript -h  #should display help $ ./myscript     #should display help 

My requirements are:

  • getopt here to get the input arguments
  • check that -s exists, if not return an error
  • check that the value after the -s is 45 or 90
  • check that the -p exists and there is an input string after
  • if the user enters ./myscript -h or just ./myscript then display help

I tried so far this code:

#!/bin/bash while getopts "h:s:" arg; do   case $arg in     h)       echo "usage"        ;;     s)       strength=$OPTARG       echo $strength       ;;   esac done 

But with that code I get errors. How to do it with Bash and getopt?

like image 611
MOHAMED Avatar asked May 10 '13 13:05

MOHAMED


People also ask

What does getopts mean 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. How it works. Specifying the optstring. Verbose error checking.

What is getopts in shell script?

Description. The getopts command is a Korn/POSIX Shell built-in command that retrieves options and option-arguments from a list of parameters. An option begins with a + (plus sign) or a - (minus sign) followed by a character. An option that does not begin with either a + or a - ends the OptionString.

Should I use getopt or getopts?

The main differences between getopts and getopt are as follows: getopt does not handle empty flag arguments well; getopts does. getopts is included in the Bourne shell and Bash; getopt needs to be installed separately. getopt allows for the parsing of long options ( --help instead of -h ); getopts does not.

What does getopts mean?

getopt is a C library function used to parse command-line options of the Unix/POSIX style. It is a part of the POSIX specification, and is universal to Unix-like systems. It is also the name of a Unix program for parsing command line arguments in shell scripts.


2 Answers

#!/bin/bash  usage() { echo "Usage: $0 [-s <45|90>] [-p <string>]" 1>&2; exit 1; }  while getopts ":s:p:" o; do     case "${o}" in         s)             s=${OPTARG}             ((s == 45 || s == 90)) || usage             ;;         p)             p=${OPTARG}             ;;         *)             usage             ;;     esac done shift $((OPTIND-1))  if [ -z "${s}" ] || [ -z "${p}" ]; then     usage fi  echo "s = ${s}" echo "p = ${p}" 

Example runs:

$ ./myscript.sh Usage: ./myscript.sh [-s <45|90>] [-p <string>]  $ ./myscript.sh -h Usage: ./myscript.sh [-s <45|90>] [-p <string>]  $ ./myscript.sh -s "" -p "" Usage: ./myscript.sh [-s <45|90>] [-p <string>]  $ ./myscript.sh -s 10 -p foo Usage: ./myscript.sh [-s <45|90>] [-p <string>]  $ ./myscript.sh -s 45 -p foo s = 45 p = foo  $ ./myscript.sh -s 90 -p bar s = 90 p = bar 
like image 96
Adrian Frühwirth Avatar answered Sep 29 '22 04:09

Adrian Frühwirth


The problem with the original code is that:

  • h: expects parameter where it shouldn't, so change it into just h (without colon)
  • to expect -p any_string, you need to add p: to the argument list

Basically : after the option means it requires the argument.


The basic syntax of getopts is (see: man bash):

getopts OPTSTRING VARNAME [ARGS...] 

where:

  • OPTSTRING is string with list of expected arguments,

    • h - check for option -h without parameters; gives error on unsupported options;
    • h: - check for option -h with parameter; gives errors on unsupported options;
    • abc - check for options -a, -b, -c; gives errors on unsupported options;
    • :abc - check for options -a, -b, -c; silences errors on unsupported options;

      Notes: In other words, colon in front of options allows you handle the errors in your code. Variable will contain ? in the case of unsupported option, : in the case of missing value.

  • OPTARG - is set to current argument value,

  • OPTERR - indicates if Bash should display error messages.

So the code can be:

#!/usr/bin/env bash usage() { echo "$0 usage:" && grep " .)\ #" $0; exit 0; } [ $# -eq 0 ] && usage while getopts ":hs:p:" arg; do   case $arg in     p) # Specify p value.       echo "p is ${OPTARG}"       ;;     s) # Specify strength, either 45 or 90.       strength=${OPTARG}       [ $strength -eq 45 -o $strength -eq 90 ] \         && echo "Strength is $strength." \         || echo "Strength needs to be either 45 or 90, $strength found instead."       ;;     h | *) # Display help.       usage       exit 0       ;;   esac done 

Example usage:

$ ./foo.sh  ./foo.sh usage:     p) # Specify p value.     s) # Specify strength, either 45 or 90.     h | *) # Display help. $ ./foo.sh -s 123 -p any_string Strength needs to be either 45 or 90, 123 found instead. p is any_string $ ./foo.sh -s 90 -p any_string Strength is 90. p is any_string 

See: Small getopts tutorial at Bash Hackers Wiki

like image 45
kenorb Avatar answered Sep 29 '22 05:09

kenorb