Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boolean cli flag using getopts in bash?

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.

like image 768
foobar0100 Avatar asked Aug 12 '15 20:08

foobar0100


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.

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.

What is Optind in Bash?

$OPTIND is the number of options found by getopts . As pauljohn32 mentions in the comments, strictly speaking, OPTIND gives the position of the next command line argument. From the GNU Bash Reference Manual: getopts optstring name [args] getopts is used by shell scripts to parse positional parameters.

What is Optarg in shell script?

OPTIND and OPTARG are local to the shell script. If you want to export them, you must do so explicitly. If the script invoking getopts sets OPTIND to 1 , it can call getopts again with a new set of parameters, either the current positional parameters or new arg values.


1 Answers

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

like image 160
UrsaDK Avatar answered Oct 10 '22 11:10

UrsaDK