Option parsing in Bash

Flag

Script

  • A switch or simple Boolean option.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/bin/bash

    while [ True ]; do
    if [ "$1" = "--alpha" -o "$1" = "-a" ]; then
    ALPHA=1
    shift 1
    else
    break
    fi
    done

    echo $ALPHA
  • Steps

    • Infinite loop until break instruction is reached on if.
    • The if statement attempts to match whatever argument is found in the first position ($1) to either --alpha or -a.
    • Prints the value of ALPHA when it finishes.

Test the script

  • It detects the --alpha argument.

    1
    2
    $ bash ./test.sh --alpha
    1
  • It detects the --a argument.

    1
    2
    $ bash ./test.sh -a
    1
  • No --alpha or -a argument, no output.

    1
    2
    $ bash ./test.sh

  • Extra arguments are ignored.

    1
    2
    3
    $ bash ./test.sh --alpha foo
    1
    $

Detecting arguments

Script

  • Catch arguments that aren’t intended as options: dump remaining arguments into a Bash array.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #!/bin/bash

    while [ True ]; do
    if [ "$1" = "--alpha" -o "$1" = "-a" ]; then
    ALPHA=1
    shift 1
    else
    break
    fi
    done

    echo $ALPHA

    ARG=( "${@}" )
    for i in ${ARG[@]}; do
    echo $i
    done

Test the script

  • It detects the --alpha argument, and also types foo.

    1
    2
    3
    $ bash ./test.sh --alpha foo
    1
    foo
  • No --alpha argument so the output line is empty, it types foo after that empty line.

    1
    2
    3
    $ bash ./test.sh foo

    foo
  • It detects the --alpha argument, and also types foo and bar.

    1
    2
    3
    4
    $ bash ./test.sh --alpha foo bar
    1
    foo
    bar

Options with arguments

Script

  • Some options require an argument all their own.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #!/bin/bash

    while [ True ]; do
    if [ "$1" = "--alpha" -o "$1" = "-a" ]; then
    ALPHA=1
    shift 1
    elif [ "$1" = "--config" -o "$1" = "-c" ]; then
    CONFIG=$2
    shift 2
    else
    break
    fi
    done

    echo $ALPHA
    echo $CONFIG

    ARG=( "${@}" )

    for i in ${ARG[@]}; do
    echo $i
    done
  • To implement this, you can use the shift keyword as you did on the switch, but shift the arguments by 2 instead of 1.

  • elif compares each argument to both --config and -c.

    • If match: the value of a variable called CONFIG is set to the value of whatever the second argument is.
    • This means that the –config option requires an argument.
    • All arguments shift place by 2: 1 to shift --config or -c, and 1 to move its argument.

Test the script

1
2
3
4
$ bash ./test.sh --config my.conf foo bar
my.conf
foo
bar
1
2
3
4
$ bash ./test.sh -a --config my.conf baz
1
my.conf
baz