There’re many ways to parse arguments that were passed to a bash script. I’ll show two similar methods to parse the parameter schema -o /foo/ and --output=/foo/ . The second example can also handle commands.

String manipulation just using Bash

If you’re not familiar with manipulation of string (like ${var#=*} or similar) keep on reading. We’ll select sub-strings from the arguments in the following scripts. The command to do so looks like this: ${<VARIABLE><SPLIT-CHARS><REGEX>}

The split chars define what the result is, which is always one single string. There’re four different ones:

# Removes the shortest match from the beginning:

$var="ab=cd=ef"

${var#*=}

The result is cd=ef , because ab= is the shortest match. ## Removes the longest match from the beginning:

$var="ab=cd=ef"

${var##*=}

The result is ef , because ab=cd= is the longest match. % Removes the shortest match from the end:

$var="ab=cd=ef"

${var%=*} (attention, the star is now behind the equals 😉 )

The result is ab=cd , because =ef is the shortest match. %% Removes the longest match from the end:

$var="ab=cd=ef"

${var%%=*}

The result is ab , because =cd=ef is the longest match.

We’ll use these operation to determine the value of a parameter. For --package=foo the result should be foo .

For more information on string manipulations, have a look at https://www.tldp.org/LDP/abs/html/string-manipulation.html.

The format of the arguments

I mostly follow the POSIX standard with the GNU extension for long arguments. That means that the following arguments are valid:

-h

--help

-p foo

--package=foo

I ignore things like -hv (for -h and -v ) or -pfoo (as equivalent for -p foo ) to keep it simple.

Simple example

A working bash script can be found here: https://gist.github.com/hauke96/2e8c8630906bc5253c84ed83751e045b

Many people use the while loop to iterate over the arguments. That results in having many shift statements to move to the next argument and I find it kind of unhandy. I’m also a fan of having an index I can work with and therefore I use the for loop. When an argument is separated by a space (e.g. -p foo ) from its value, $i needs to be incremented manually.

Example with commands

Commands are basically subroutines of the actual program and might have their own arguments. The command apt-get install ... for example takes multiple packages as arguments, whereas apt-get update doesn’t allow any arguments.

A working bash script can be found here: https://gist.github.com/hauke96/d069bcf32ec35c66412e9ee50b0295a8

The format I use is bash command.sh <COMMAND> <ARGUMENTS>

First the command (which is <COMMAND> in the format above) will be parsed using arg=${@:1:1} . The only allowed command in the example is install .

Because each command can have own arguments, those are parsed in the parse_install_args . This function then looks like the routine in the simple example.

Alternatives

As I said before, many people are using the while loop. Other implementations can be found for example on Stackoverflow.