Bash Shell Script - Check for a flag and grab its value Bash Shell Script - Check for a flag and grab its value linux linux

Bash Shell Script - Check for a flag and grab its value


You should read this getopts tutorial.

Example with -a switch that requires an argument :

#!/bin/bashwhile getopts ":a:" opt; do  case $opt in    a)      echo "-a was triggered, Parameter: $OPTARG" >&2      ;;    \?)      echo "Invalid option: -$OPTARG" >&2      exit 1      ;;    :)      echo "Option -$OPTARG requires an argument." >&2      exit 1      ;;  esacdone

Like greybot said(getopt != getopts) :

The external command getopt(1) is never safe to use, unless you know it is GNU getopt, you call it in a GNU-specific way, and you ensure that GETOPT_COMPATIBLE is not in the environment. Use getopts (shell builtin) instead, or simply loop over the positional parameters.


Use $# to grab the number of arguments, if it is unequal to 2 there are not enough arguments provided:

if [ $# -ne 2 ]; then   usage;fi

Next, check if $1 equals -t, otherwise an unknown flag was used:

if [ "$1" != "-t" ]; then  usage;fi

Finally store $2 in FLAG:

FLAG=$2

Note: usage() is some function showing the syntax. For example:

function usage {   cat << EOFUsage: script.sh -t <application>Performs some activityEOF   exit 1}


Here is a generalized simple command argument interface you can paste to the top of all your scripts.

#!/bin/bashdeclare -A flagsdeclare -A booleansargs=()while [ "$1" ];do    arg=$1    if [ "${1:0:1}" == "-" ]    then      shift      rev=$(echo "$arg" | rev)      if [ -z "$1" ] || [ "${1:0:1}" == "-" ] || [ "${rev:0:1}" == ":" ]      then        bool=$(echo ${arg:1} | sed s/://g)        booleans[$bool]=true        echo \"$bool\" is boolean      else        value=$1        flags[${arg:1}]=$value        shift        echo \"$arg\" is flag with value \"$value\"      fi    else      args+=("$arg")      shift      echo \"$arg\" is an arg    fidoneecho -e "\n"echo booleans: ${booleans[@]}echo flags: ${flags[@]}echo args: ${args[@]}echo -e "\nBoolean types:\n\tPrecedes Flag(pf): ${booleans[pf]}\n\tFinal Arg(f): ${booleans[f]}\n\tColon Terminated(Ct): ${booleans[Ct]}\n\tNot Mentioned(nm): ${boolean[nm]}"echo -e "\nFlag: myFlag => ${flags["myFlag"]}"echo -e "\nArgs: one: ${args[0]}, two: ${args[1]}, three: ${args[2]}"

By running the command:

bashScript.sh firstArg -pf -myFlag "my flag value" secondArg -Ct: thirdArg -f

The output will be this:

"firstArg" is an arg"pf" is boolean"-myFlag" is flag with value "my flag value""secondArg" is an arg"Ct" is boolean"thirdArg" is an arg"f" is booleanbooleans: true true trueflags: my flag valueargs: firstArg secondArg thirdArgBoolean types:    Precedes Flag(pf): true    Final Arg(f): true    Colon Terminated(Ct): true    Not Mentioned(nm): Flag: myFlag => my flag valueArgs: one => firstArg, two => secondArg, three => thirdArg

Basically, the arguments are divided up into flags booleans and generic arguments.By doing it this way a user can put the flags and booleans anywhere as long as he/she keeps the generic arguments (if there are any) in the specified order.

Allowing me and now you to never deal with bash argument parsing again!

You can view an updated script here

This has been enormously useful over the last year. It can now simulate scope by prefixing the variables with a scope parameter.

Just call the script like

replace() (  source $FUTIL_REL_DIR/commandParser.sh -scope ${FUNCNAME[0]} "$@"  echo ${replaceFlags[f]}  echo ${replaceBooleans[b]})

Doesn't look like I implemented argument scope, not sure why I guess I haven't needed it yet.