Shell Snippets

Date: , Updated: — Topic: — Langs: , — by Slatian

The snippets on this site are intended for getting copied and being useful so please do that.

Argument Parser

A simple argument parser for bash.

#!/bin/bash

# Make the script fail when a command fails
set -e

# Settings variables go here
FOO="foo"

show_help() {
cat <<EOF
Usage: foo <<options>> <bar>

Blubber blah blah ...
EOF
}

while [[ "$#" -gt 0 ]]; do
	case "$1" in
		--foo)
			FOO="$2"
			shift 2;;
		
		--help) show_help; exit 0;;
		*) printf "Unknown option: %s\n" "$1"; exit 1;;
	esac
done

# Logic goes here
echo "$FOO"

set -e and shift

The set -e option tells the shell to stop executing a script once a command fails. This is important when using a shift in this kind of while loop where the loop exiting depends on the shift working.

Example: The shift may fail if it is told to move 2 arguments out (shift 2) but there is only one given. In the example above that would be fulfilled when passing --foo as the last argument (a relatively easy to make mistake). If the shift silently failed the argument counter would never reach 0 and the script would be stuck in an endless loop.

Hook Helper

This little function calls its argument as an ad-hoc shellscript if it is non-empty, if it returns a nonzero, one should call the default action.

# on fail do default action
run_hook() {
	[ -n "$1" ] && bash -c "$1"
}
Example of how this little helper is intended to be used
export VARIABLE_WHICH_IS_USEFUL_FOR_HOOK="something"
run_hook "$HOOK_COMMAND" || default_action

An example of this being used can be found in my dotfiles with the filedialog. (Fun fact: It was created for this script)

Grep Regex Match Helper

This function pipes its first argument into a grep -q command which is given the rest of the arguments.

matches() {
	TEXT="$1"
	shift 1
	printf "%s\n" "$TEXT" | grep -q "$@"
}

Example usage: matches "$FOO" "^[0-9]$" && echo "FOO is a number! :)" || FOO=0

It can also be useful to implement some kind of heuristics based on which patterns occur in a text.

Bash Arrays

Bash has arrays so one doesn't have to care about delimiters too much.

Note on compatibility: These arrays only work in bash which isn't isntalled everywhere (dash is a popular alternative). Please use #!/bin/bash instead of #!/bin/sh to indicate that your script requires bash to work.

Create an array:

empty_array=()
array=('text' "can go" "$( echo here )" ";")

Appending to an exisiting Array:

array+=("foo")
array+=("add" "multiple" "elements")

These can then be accessed with 0 based indices:

echo "${array[1]}"
# prints out: can go

To get the number of elements in an array:

echo "${#array[*]}"
echo "${#array[@]}"

An array can expand to multiple arguments:

printf "-> %s" "${array[@]}"
# Compare with the output of:
printf "-> %s" foo bar baz

Which is also useful for for-loops:

for i in "${array[@]}" ; do
	echo "-> $i"
done

And to clean up:

# remove element at index 1
uset array[1]
# remove the whole array
uset array

There is more to bash arrays (including associative arrays) …

Check out The Bash Reference Manual on Arrays

See Also