How can a Bash function detect whether it is being used with positional or named arguments?

132 views Asked by At

I'm writing a Bash function that is to be capable of attempting to use either positional or named arguments, whereby positional arguments are accessed in the usual "${1}", "${2}" way and named arguments are accessed using getopts. I have some example code and example usage shown below in order to illustrate what I'm trying to do. The problem is that the check I'm doing on the variable ${*} is just a grep for the character -, which limits greatly the character content of further arguments. What would be a more intelligent or robust way of checking for named arguments in Bash?

example code:

function1(){
    # flags
        argumentsFlag1=""
            # n: named arguments
            # p: positional arguments
        verboseFlag1="0"
            # v: verbose
        silentFlag1="0"
            # 0: standard output
            # 1: no standard output
    # options and arguments
        # Determine if positional or named arguments are used.
            # If the arguments contain "-", then named arguments are assumed,
            # otherwise positional arguments are assumed.
                if [ "$(echo "${*}" | grep "-")" ]; then
                    argumentsFlag1="n"
                else
                   argumentsFlag1="p"
                fi
        # handle named arguments
            if [ "${argumentsFlag1}" == "n" ]; then
                OPTIND=1; while getopts "i:sv" options; do
                    case "${options}" in
                        i)
                            input1="${OPTARG}"
                            ;;
                        v)
                            verboseFlag1=1
                            ;;
                        s)
                            silentFlag1=0
                            ;;
                        \?)
                            echo "invalid option -"${OPTARG}""
                            return
                            ;;
                        :)
                            echo "option -"${OPTARG}" requires an argument"
                            return
                            ;;
                    esac
                done
        # handle positional arguments
            elif [ "${argumentsFlag1}" == "p" ]; then
                input1="${1}"
        fi
    # default values
        if [ -z "${verboseFlag1}" ]; then
            verboseFlag1=0
        fi
# ------------------------------------------------------------------------------
    if  [ "${argumentsFlag1}" == "n" ]; then
        echo "named arguments assumed"
    elif [ "${argumentsFlag1}" == "p" ]; then
        echo "positional arguments assumed"
    fi
    echo "input: "${input1}""
}

example usage:

$ function1 zappo
positional arguments assumed
input: zappo

$ function1 -i zappo
named arguments assumed
input: zappo

EDIT: Please note that I am not trying to use positional and named arguments at the same time. I am trying to get the function to have a state in which it is interpreting the arguments solely as positional or solely for interpretation by getopts as a mix of positional and named arguments. There are to be instances in which getopts is not used. Imagine the following idea...

I have a function that is used from one data type to another. This function has two modes:

quick mode

This mode can be used in a manner such as the following:

function fileName1 fileName2

It converts one file to another using internal assumptions and measurements made autonomously.

advanced mode

This mode can be used in a manner such as the following:

function -i fileName1 -o fileName2 -m -r 100 -v

There can be positional arguments used in this mode, but they must be placed after the getopts positional options and arguments.

1

There are 1 answers

3
Donovan On

Use getopts to process any named arguments, shifting them off the stack as you do so. If any remain afterward, they are your positional arguments.