Skip to content

Instantly share code, notes, and snippets.

@mvoitko
Created Jul 7, 2020
Embed
What would you like to do?
Bash script template
#!/bin/bash
################################################################################
# scriptTemplate
################################################################################
################################################################################
################################################################################
# #
# Copyright (C) 2020 Maksym Voitko #
# max.voitko@gmail.com #
# #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation; either version 2 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program; if not, write to the Free Software #
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #
# #
################################################################################
################################################################################
################################################################################
# Run in debug mode, if set
if [ "${debug}" == "1" ]; then
set -x
fi
# Exit on empty variable
if [ "${strict}" == "1" ]; then
set -o nounset
fi
set -o errexit # Exit immediately when it encounters a non-zero exit code from an executed command
set -o errtrace # Make sure any error trap is inherited
set -o pipefail # Use last non-zero exit code in a pipeline
log_level_for()
{
case "${1}" in
"error")
echo 1
;;
"warn")
echo 2
;;
"debug")
echo 3
;;
"info")
echo 4
;;
*)
echo -1
;;
esac
}
current_log_level()
{
log_level_for "${LOG_LEVEL}"
}
error()
{
[ $(log_level_for "error") -le $(current_log_level) ] && echo "${1}" >&2
}
warn()
{
[ $(log_level_for "warn") -le $(current_log_level) ] && echo "${1}" >&2
}
debug()
{
[ $(log_level_for "debug") -le $(current_log_level) ] && echo "${1}" >&2
}
info()
{
[ $(log_level_for "info") -le $(current_log_level) ] && echo "${1}" >&2
}
# DESC: Handler for unexpected errors
# ARGS: $1 (optional): Exit code (defaults to 1)
# OUTS: None
function script_trap_err() {
local exit_code=1
# Disable the error trap handler to prevent potential recursion
trap - ERR
# Consider any further errors non-fatal to ensure we run to completion
set +o errexit
set +o pipefail
# Validate any provided exit code
if [[ ${1-} =~ ^[0-9]+$ ]]; then
exit_code="$1"
fi
# Output debug data if in Cron mode
if [[ -n ${cron-} ]]; then
# Restore original file output descriptors
if [[ -n ${script_output-} ]]; then
exec 1>&3 2>&4
fi
# Print basic debugging information
printf '%b\n' "$ta_none"
printf '***** Abnormal termination of script *****\n'
printf 'Script Path: %s\n' "$script_path"
printf 'Script Parameters: %s\n' "$script_params"
printf 'Script Exit Code: %s\n' "$exit_code"
# Print the script log if we have it. It's possible we may not if we
# failed before we even called cron_init(). This can happen if bad
# parameters were passed to the script so we bailed out very early.
if [[ -n ${script_output-} ]]; then
printf 'Script Output:\n\n%s' "$(cat "$script_output")"
else
printf 'Script Output: None (failed before log init)\n'
fi
fi
# Exit with failure status
exit "$exit_code"
}
# DESC: Handler for exiting the script
# ARGS: None
# OUTS: None
function script_trap_exit() {
cd "$orig_cwd"
# Remove Cron mode script log
if [[ -n ${cron-} && -f ${script_output-} ]]; then
rm "$script_output"
fi
# Remove script execution lock
if [[ -d ${script_lock-} ]]; then
rmdir "$script_lock"
fi
# Restore terminal colours
printf '%b' "$ta_none"
}
# DESC: Exit script with the given message
# ARGS: $1 (required): Message to print on exit
# $2 (optional): Exit code (defaults to 0)
# OUTS: None
# NOTE: The convention used in this script for exit codes is:
# 0: Normal exit
# 1: Abnormal exit due to external error
# 2: Abnormal exit due to script error
function script_exit() {
if [[ $# -eq 1 ]]; then
printf '%s\n' "$1"
exit 0
fi
if [[ ${2-} =~ ^[0-9]+$ ]]; then
printf '%b\n' "$1"
# If we've been provided a non-zero exit code run the error trap
if [[ $2 -ne 0 ]]; then
script_trap_err "$2"
else
exit 0
fi
fi
script_exit 'Missing required argument to script_exit()!' 2
}
# DESC: Parameter parser
# ARGS: $@ (optional): Arguments provided to the script
# OUTS: Variables indicating command-line parameters and options
function parse_params() {
local param
while [[ $# -gt 0 ]]; do
param="$1"
shift
case $param in
-h | --help)
script_usage
exit 0
;;
-v | --verbose)
verbose=true
;;
-nc | --no-colour)
no_colour=true
;;
-cr | --cron)
cron=true
;;
*)
script_exit "Invalid parameter was provided: $param" 1
;;
esac
done
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment