9

Is it possible to implement a boolean cli option using getopts in bash? Basically I want to do one thing if -x is specified and another if it is not.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
foobar0100
  • 291
  • 1
  • 3
  • 9
  • search for `[bash] getopts case` good luck. – shellter Aug 12 '15 at 20:15
  • 1
    Yes; set a variable: `opt_x="";` before the `getopts` loop; set `opt_x="-x"` inside the `case` inside the `getopts` loop. Test the value in `$opt_x` after the loop. You can use `opt_x="no"` and `opt_x="yes"` if you prefer, or any other convention. Observe the use of `vflag` in [Shell script templates](http://stackoverflow.com/questions/430078/shell-script-templates/430680?s=2|0.0000#430680) for another convention. – Jonathan Leffler Aug 12 '15 at 21:22

1 Answers1

12

Of course it is possible. @JonathanLeffler already pretty much gave the answer in the comments to the question, so all I'm going to do here is add an example of the implementation and a few niceties to consider:

#!/usr/bin/env bash

# Initialise option flag with a false value
OPT_X='false'

# Process all options supplied on the command line 
while getopts ':x' 'OPTKEY'; do
    case ${OPTKEY} in
        'x')
            # Update the value of the option x flag we defined above
            OPT_X='true'
            ;;
        '?')
            echo "INVALID OPTION -- ${OPTARG}" >&2
            exit 1
            ;;
        ':')
            echo "MISSING ARGUMENT for option -- ${OPTARG}" >&2
            exit 1
            ;;
        *)
            echo "UNIMPLEMENTED OPTION -- ${OPTKEY}" >&2
            exit 1
            ;;
    esac
done

# [optional] Remove all options processed by getopts.
shift $(( OPTIND - 1 ))
[[ "${1}" == "--" ]] && shift

# "do one thing if -x is specified and another if it is not"
if ${OPT_X}; then
    echo "Option x was supplied on the command line"
else
    echo "Option x was not supplied on the command line"
fi

A few notes about the above example:

  • true and false are used as option x indicators because both are valid UNIX commands. This makes the test for the option presence more readable, in my opinion.

  • getopts is configured to run in silent error reporting mode because it suppressed default error messages and allows for a more precise error handling.

  • the example includes fragments of code for dealing with missing option arguments and post-getopts command line arguments. These are not part of the OP's question.

    They are added for the sake of completeness as this code will be required in any reasonably complex script.

For more information about getopts see Bash Hackers Wiki: Small getopts tutorial

Raffi Khatchadourian
  • 3,042
  • 3
  • 31
  • 37
UrsaDK
  • 854
  • 13
  • 27