Bash Shell Script - Check the flag and get its value

I am trying to create a shell script that is designed to run as follows:

script.sh -t application 

Firstly, in my script I want to check if the script was run with the -t flag. For example, if it was run without this flag, I want it to be an error:

 script.sh 

Secondly, assuming that the -t flag exists, I want to capture the value and store it in a variable that I can use in my script, for example, as follows:

 FLAG="application" 

So far, the only progress that I have been able to make in this is that $ @ captures all command line arguments, but I don’t know how this relates to flags, or even if it is possible.

+61
linux bash shell debian
Jan 21 '13 at 21:19
source share
4 answers

You should read this getopts tutorial.

An example with the -a switch that requires an argument:

 #!/bin/bash while 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 ;; esac done 

As grabot said ( getopt ! = getopts ):

The external getopt (1) command can never be used safely unless you know that it is GNU getopt, you invoke it in a GNU-specific way and make sure that GETOPT_COMPATIBLE is not in the environment. Instead, use getopts (built-in shell) or just switch between positional parameters.

+95
Jan 21 '13 at 21:24
source share

Use $# to grab the number of arguments, if it does not match 2, there are not enough arguments:

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

Then check if $1 -t matches, otherwise an unknown flag was used:

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

Finally, save $2 in FLAG :

 FLAG=$2 

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

 function usage { cat << EOF Usage: script.sh -t <application> Performs some activity EOF exit 1 } 
+24
Jan 21 '13 at 21:24
source share

Here is a generic simple command argument interface that you can insert at the beginning of all your scripts.

 #!/bin/bash declare -A flags declare -A booleans args=() 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 fi done echo -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 like 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 boolean booleans: true true true flags: my flag value args: firstArg secondArg thirdArg Boolean types: Precedes Flag(pf): true Final Arg(f): true Colon Terminated(Ct): true Not Mentioned(nm): Flag: myFlag => my flag value Args: one => firstArg, two => secondArg, three => thirdArg 

Basically, arguments are divided into logical flags and general arguments. By doing this in this way, the user can set flags and booleans anywhere, as long as he / she saves the general arguments (if any) in that order.

Let me and now you never have to deal with parsing bash arguments again!

You can view the updated script here

This has been extremely helpful over the past year. Now it can simulate the scope by adding variables to the scope parameter.

Just name the script as

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

It doesn't look like I implemented the scope of the argument, not sure why, I think, I don't need it yet.

+6
Sep 03 '18 at 22:04
source share

Try shFlags - An extended command line flag library for Unix shell scripts.

http://code.google.com/p/shflags/

It is very good and very flexible.

FLAG TYPES: This is the DEFINE_ * list you can do. All flags are name, default value, help line and optional "short" name (single-letter name). Some flags have other arguments that are described using the flag.

DEFINE_string: accepts any input and interprets it as a string.

DEFINE_boolean: usually takes no arguments: say --myflag to set FLAGS_myflag to true, or --nomyflag to set FLAGS_myflag to false. Alternatively, you can say --myflag = true or --myflag = t or --myflag = 0 or --myflag = false or --myflag = f or --myflag = 1 Passing the parameter has the same effect as transition options.

DEFINE_float: takes input and interprets it as a floating point number. As a shell, it does not support floats per se; the input is simply checked as being a valid floating point value.

DEFINE_integer: takes input and interprets it as an integer.

SPECIAL FLAGS: There are several flags that have special meaning: --help (or -?) Prints a list of all flags in a human-readable way --flagfile = foo read flags from foo. (not yet implemented) - as in getopt (), completes flag processing

EXAMPLE OF USE:

 -- begin hello.sh -- ! /bin/sh . ./shflags DEFINE_string name 'world' "somebody name" n FLAGS "$@" || exit $? eval set -- "${FLAGS_ARGV}" echo "Hello, ${FLAGS_name}." -- end hello.sh -- $ ./hello.sh -n Kate Hello, Kate. 

Note. I took this text from shflags documentation

0
Nov 06 '17 at 18:43
source share



All Articles