Script Template for Bash

I usually use that template for bash but I try to keep it compatible with sh anq zsh.

The script only supports simple parameters with one character. For example, a -h will print the following help text:

Call:   ./template.sh <Optionen> <Parameter>
Template for bash scripts.

The following parameters are optional:
  -h          Print this help and exit the script.
  -x          Parameter.
  -y <VAL>    Another parameter. Default: Default
  -v          Be more verbose. Can be used multiple times.

Options and additional parameters must not be mixed.

Template

Download Script

#!/bin/bash

# Copyright (c) 2014 Christian Mauderer <oss@c-mauderer.de>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

# exit on wrong command and undefined variable
set -e
set -u
# The following one only works for bash. It catches the fail of the first
# command in a pipe. e.g. 'which asdf | true' would fail due to the missing asdf
# command.
set -o pipefail

PARAM1=0
PARAM2="Default"
VERBOSE=0

SCRIPTNAME=$0

# Print a error message and exits with 1
# Arguments:
#	0: message
printerror () {
	echo "ERROR: $1"
	echo ""
	echo "Call with \"${SCRIPTNAME} -h\" for help."
	exit 1
}

# Check if the parameter is a program. Print error and exit if not.
# Arguments:
#	0: program name
test_command () {
	if ! which $1 >/dev/null 2>&1
	then
		printerror "Command \"$1\" not found."
	fi
}

# Print a message depending on verbose level (set in ${VERBOSE}).
# Arguments:
#	0: message will be printed on this level
#	1: message
print_msg () {
	local LEVEL="$1"
	local MSG="$2"

	if [ ${LEVEL} -le ${VERBOSE} ]
	then
		echo "${MSG}"
	fi
}

# Print a help text and exit
# Arguments:
#	n.a.
printhelp () {
	echo ""
	echo "Call:   ${SCRIPTNAME} <options> <parameters>"
	echo "Template for bash scripts. Needs at least one parameter."
	echo ""
	echo "The following parameters are optional:"
	echo "  -h          Print this help and exit the script."
	echo "  -x          Parameter."
	echo "  -y <VAL>    Another parameter. Default: ${PARAM2}"
	echo "  -v          Be more verbose. Can be used multiple times."
	exit 0
}

# The main script

# Read options
while getopts "hxy:v" OPTION
do
	case ${OPTION} in
		h)  printhelp ;;
		x)  PARAM1=1 ;;
		y)  PARAM2=${OPTARG} ;;
		v)  VERBOSE=$((${VERBOSE} + 1)) ;;
		\?) printerror "Unknown option \"-${OPTARG}\"." ;;
		:)  printerror "Option \"-${OPTARG}\" needs an argument." ;;
	esac
done
# Remove the already processed ones
shift $((${OPTIND} - 1))

# Process all parameters without dash
[[ $# -lt 1 ]] && printerror "Needs at least one parameter."
PARAMETER="$1"

# Check commands
# Not necessary in this case. But there is an example:
# test_command "vim"

# Do something
print_msg 1 "Verbose level: ${VERBOSE}"
print_msg 1 "Parameter: ${PARAMETER}"
print_msg 2 "-x: ${PARAM1}"
print_msg 2 "-y: ${PARAM2}"

# vim: set ts=4 sw=4: