BASH getopts optional arguments

Villi Magg picture Villi Magg · Jun 10, 2013 · Viewed 10.1k times · Source

I'm trying to create a shell script that has two mandatory arguments (arg1, arg2) and then an optional -b flag plus the argument that needs to follow should the user choose to use the flag.

Let me explain:

It's an install script that takes an advantage of GIT to fetch an application from a Github repository. The user types in terminal f.ex.:

./shellscript.sh new <app_name> # fetches master branch by default

and the script fetches an instance of the master branch from this repository. Should the user however choose to use the optional -b flag that would mean that he/she wants to specify which branch to fetch, e.g. develop branch. Meaning that the user could do:

./shellscript.sh new <app_name> -b develop # or which ever branch there is available

I'm also curious how you could go about making the script work so that it wouldn't matter if the user types in the -b flag+branch_name before the 'new' argument and the 'app_name' argument. But that is perhaps not the most important thing at the moment.

To know what exactly I'm trying to build, here is a link to my current script that only takes the two mandatory arguments and only fetches the master branch: My Super Cool Artisan Executable Script

P.S.: I've been trying out many examples using getopts which I've found both here on Stackoverflow and other blogs out there but none have helped me to completely make it work. Thus am I here asking y'all great people for help.

Huge thanks and be sure to check out my Linux Mint / Ubuntu - Post Install Script for only cool people(you guys and those switching over to Linux from Windows/Mac)

Regards, Villi

Answer

cforbish picture cforbish · Jun 10, 2013

I normally write my own to allow for short and long options:

function Usage()
{
cat <<-ENDOFMESSAGE

$0 [OPTION] REQ1 REQ2

options:

    -b -branch  branch to use
    -h --help   display this message

ENDOFMESSAGE
    exit 1
}

function Die()
{
    echo "$*"
    exit 1
}

function GetOpts() {
    branch=""
    argv=()
    while [ $# -gt 0 ]
    do
        opt=$1
        shift
        case ${opt} in
            -b|--branch)
                if [ $# -eq 0 -o "${1:0:1}" = "-" ]; then
                    Die "The ${opt} option requires an argument."
                fi
                branch="$1"
                shift
                ;;
            -h|--help)
                Usage;;
            *)
                if [ "${opt:0:1}" = "-" ]; then
                    Die "${opt}: unknown option."
                fi
                argv+=(${opt});;
        esac
    done 
}

GetOpts $*
echo "branch ${branch}"
echo "argv ${argv[@]}"