bashgetopts

bash getopts with multiple and mandatory options


Is it possible to use getopts to process multiple options together? For example, myscript -iR or myscript -irv.

Also, I have a situation where based on a condition script would need mandatory option. For example, if argument to script is a directory, I will need to specify -R or -r option along with any other options (myscript -iR mydir or myscript -ir mydir or myscript -i -r mydir or myscript -i -R mydir), in case of file only -i is sufficient (myscript -i myfile).

I tried to search but didn't get any answers.


Solution

  • You can concatenate the options you provide and getopts will separate them. In your case statement you will handle each option individually.

    You can set a flag when options are seen and check to make sure mandatory "options" (!) are present after the getopts loop has completed.

    Here is an example:

    #!/bin/bash
    rflag=false
    small_r=false
    big_r=false
        
    usage () { echo "How to use"; }
        
    options=':ij:rRvhm'
    while getopts $options option
    do
        case "$option" in
            i  ) i_func;;
            j  ) j_arg=$OPTARG;;
            r  ) rflag=true; small_r=true;;
            R  ) rflag=true; big_r=true;;
            v  ) v_func; other_func;;
            h  ) usage; exit;;
            \? ) echo "Unknown option: -$OPTARG" >&2; exit 1;;
            :  ) echo "Missing option argument for -$OPTARG" >&2; exit 1;;
            *  ) echo "Unimplemented option: -$option" >&2; exit 1;;
        esac
    done
    
    if ((OPTIND == 1))
    then
        echo "No options specified"
    fi
    
    shift $((OPTIND - 1))
    
    if (($# == 0))
    then
        echo "No positional arguments specified"
    fi
        
    if ! $rflag && [[ -d $1 ]]
    then
        echo "-r or -R must be included when a directory is specified" >&2
        exit 1
    fi
    

    This represents a complete reference implementation of a getopts function, but is only a sketch of a larger script.