How to get arguments with flags in Bash

后端 未结 11 2110
余生分开走
余生分开走 2020-12-22 15:56

I know that I can easily get positioned parameters like this in bash:

$0 or $1

I want to be able to use flag options like this to s

11条回答
  •  天命终不由人
    2020-12-22 16:07

    So here it is my solution. I wanted to be able to handle boolean flags without hyphen, with one hyphen, and with two hyphen as well as parameter/value assignment with one and two hyphens.

    # Handle multiple types of arguments and prints some variables
    #
    # Boolean flags
    # 1) No hyphen
    #    create   Assigns `true` to the variable `CREATE`.
    #             Default is `CREATE_DEFAULT`.
    #    delete   Assigns true to the variable `DELETE`.
    #             Default is `DELETE_DEFAULT`.
    # 2) One hyphen
    #      a      Assigns `true` to a. Default is `false`.
    #      b      Assigns `true` to b. Default is `false`.
    # 3) Two hyphens
    #    cats     Assigns `true` to `cats`. By default is not set.
    #    dogs     Assigns `true` to `cats`. By default is not set.
    #
    # Parameter - Value
    # 1) One hyphen
    #      c      Assign any value you want
    #      d      Assign any value you want
    #
    # 2) Two hyphens
    #   ... Anything really, whatever two-hyphen argument is given that is not
    #       defined as flag, will be defined with the next argument after it.
    #
    # Example:
    # ./parser_example.sh delete -a -c VA_1 --cats --dir /path/to/dir
    parser() {
        # Define arguments with one hyphen that are boolean flags
        HYPHEN_FLAGS="a b"
        # Define arguments with two hyphens that are boolean flags
        DHYPHEN_FLAGS="cats dogs"
    
        # Iterate over all the arguments
        while [ $# -gt 0 ]; do
            # Handle the arguments with no hyphen
            if [[ $1 != "-"* ]]; then
                echo "Argument with no hyphen!"
                echo $1
                # Assign true to argument $1
                declare $1=true
                # Shift arguments by one to the left
                shift
            # Handle the arguments with one hyphen
            elif [[ $1 == "-"[A-Za-z0-9]* ]]; then
                # Handle the flags
                if [[ $HYPHEN_FLAGS == *"${1/-/}"* ]]; then
                    echo "Argument with one hyphen flag!"
                    echo $1
                    # Remove the hyphen from $1
                    local param="${1/-/}"
                    # Assign true to $param
                    declare $param=true
                    # Shift by one
                    shift
                # Handle the parameter-value cases
                else
                    echo "Argument with one hyphen value!"
                    echo $1 $2
                    # Remove the hyphen from $1
                    local param="${1/-/}"
                    # Assign argument $2 to $param
                    declare $param="$2"
                    # Shift by two
                    shift 2
                fi
            # Handle the arguments with two hyphens
            elif [[ $1 == "--"[A-Za-z0-9]* ]]; then
                # NOTE: For double hyphen I am using `declare -g $param`.
                #   This is the case because I am assuming that's going to be
                #   the final name of the variable
                echo "Argument with two hypens!"
                # Handle the flags
                if [[ $DHYPHEN_FLAGS == *"${1/--/}"* ]]; then
                    echo $1 true
                    # Remove the hyphens from $1
                    local param="${1/--/}"
                    # Assign argument $2 to $param
                    declare -g $param=true
                    # Shift by two
                    shift
                # Handle the parameter-value cases
                else
                    echo $1 $2
                    # Remove the hyphens from $1
                    local param="${1/--/}"
                    # Assign argument $2 to $param
                    declare -g $param="$2"
                    # Shift by two
                    shift 2
                fi
            fi
    
        done
        # Default value for arguments with no hypheb
        CREATE=${create:-'CREATE_DEFAULT'}
        DELETE=${delete:-'DELETE_DEFAULT'}
        # Default value for arguments with one hypen flag
        VAR1=${a:-false}
        VAR2=${b:-false}
        # Default value for arguments with value
        # NOTE1: This is just for illustration in one line. We can well create
        #   another function to handle this. Here I am handling the cases where
        #   we have a full named argument and a contraction of it.
        #   For example `--arg1` can be also set with `-c`.
        # NOTE2: What we are doing here is to check if $arg is defined. If not,
        #   check if $c was defined. If not, assign the default value "VD_"
        VAR3=$(if [[ $arg1 ]]; then echo $arg1; else echo ${c:-"VD_1"}; fi)
        VAR4=$(if [[ $arg2 ]]; then echo $arg2; else echo ${d:-"VD_2"}; fi)
    }
    
    
    # Pass all the arguments given to the script to the parser function
    parser "$@"
    
    
    echo $CREATE $DELETE $VAR1 $VAR2 $VAR3 $VAR4 $cats $dir
    

    Some references

    • The main procedure was found here.
    • More about passing all the arguments to a function here.
    • More info regarding default values here.
    • More info about declare do $ bash -c "help declare".
    • More info about shift do $ bash -c "help shift".

提交回复
热议问题