2014-07-23 09:27:53 +00:00
#!/usr/bin/env bash
2014-07-23 09:28:23 +00:00
# This file:
2016-02-17 12:46:05 +00:00
#
2016-06-21 11:48:08 +00:00
# - Demos BASH3 Boilerplate (change this for your script)
2013-02-25 22:39:51 +00:00
#
# Usage:
2016-02-17 12:46:05 +00:00
#
2016-06-21 11:48:08 +00:00
# LOG_LEVEL=7 ./main.sh -f /tmp/x -d (change this for your script)
2013-02-25 22:39:51 +00:00
#
2023-08-29 10:44:42 +00:00
# Based on a template by BASH3 Boilerplate vv2.7.2
2016-06-21 11:48:08 +00:00
# http://bash3boilerplate.sh/#authors
2016-11-08 20:15:46 +00:00
#
# The MIT License (MIT)
# Copyright (c) 2013 Kevin van Zonneveld and contributors
# You are not obligated to bundle the LICENSE file with your b3bp projects as long
# as you leave these references intact in the header comments of your source files.
2013-02-25 22:39:51 +00:00
2016-12-01 13:40:56 +00:00
# Exit on error. Append "|| true" if you expect an error.
2016-02-16 03:06:32 +00:00
set -o errexit
2016-06-21 11:36:48 +00:00
# Exit on error inside any functions or subshells.
set -o errtrace
2016-06-21 11:48:37 +00:00
# Do not allow use of undefined vars. Use ${VAR:-} to use an undefined VAR
2016-02-16 03:06:32 +00:00
set -o nounset
2016-06-21 11:48:37 +00:00
# Catch the error in case mysqldump fails (but gzip succeeds) in `mysqldump |gzip`
2016-02-16 03:06:32 +00:00
set -o pipefail
2016-06-21 11:48:37 +00:00
# Turn on traces, useful while debugging but commented out by default
2016-02-16 20:59:38 +00:00
# set -o xtrace
2016-02-16 03:06:32 +00:00
2016-12-14 08:54:25 +00:00
if [ [ " ${ BASH_SOURCE [0] } " != " ${ 0 } " ] ] ; then
2017-02-10 19:08:51 +00:00
__i_am_main_script = "0" # false
2016-12-14 08:54:25 +00:00
if [ [ " ${ __usage +x } " ] ] ; then
2017-02-10 19:08:51 +00:00
if [ [ " ${ BASH_SOURCE [1] } " = " ${ 0 } " ] ] ; then
__i_am_main_script = "1" # true
fi
2016-11-09 09:03:00 +00:00
__b3bp_external_usage = "true"
__b3bp_tmp_source_idx = 1
fi
else
2017-02-10 19:08:51 +00:00
__i_am_main_script = "1" # true
2016-12-14 08:54:25 +00:00
[ [ " ${ __usage +x } " ] ] && unset -v __usage
[ [ " ${ __helptext +x } " ] ] && unset -v __helptext
2016-11-09 09:03:00 +00:00
fi
2016-06-21 11:49:11 +00:00
# Set magic variables for current file, directory, os, etc.
2016-11-09 09:03:00 +00:00
__dir = " $( cd " $( dirname " ${ BASH_SOURCE [ ${ __b3bp_tmp_source_idx :- 0 } ] } " ) " && pwd ) "
__file = " ${ __dir } / $( basename " ${ BASH_SOURCE [ ${ __b3bp_tmp_source_idx :- 0 } ] } " ) "
2016-12-01 13:40:56 +00:00
__base = " $( basename " ${ __file } " .sh) "
2019-09-20 09:30:59 +00:00
# shellcheck disable=SC2034,SC2015
__invocation = " $( printf %q " ${ __file } " ) $( ( ( $# ) ) && printf ' %q' " $@ " || true)"
2016-06-23 14:20:45 +00:00
2016-06-21 11:49:11 +00:00
# Define the environment variables (and their defaults) that this script depends on
LOG_LEVEL = " ${ LOG_LEVEL :- 6 } " # 7 = debug -> 0 = emergency
NO_COLOR = " ${ NO_COLOR :- } " # true = disable color. otherwise autodetected
2013-02-25 22:39:51 +00:00
### Functions
2016-06-21 11:49:11 +00:00
##############################################################################
2013-02-25 22:39:51 +00:00
2016-11-08 12:03:26 +00:00
function __b3bp_log ( ) {
local log_level = " ${ 1 } "
shift
2016-12-01 13:40:56 +00:00
# shellcheck disable=SC2034
2018-01-21 22:02:03 +00:00
local color_debug = "\\x1b[35m"
2016-12-01 13:40:56 +00:00
# shellcheck disable=SC2034
2018-01-21 22:02:03 +00:00
local color_info = "\\x1b[32m"
2016-12-01 13:40:56 +00:00
# shellcheck disable=SC2034
2018-01-21 22:02:03 +00:00
local color_notice = "\\x1b[34m"
2016-12-01 13:40:56 +00:00
# shellcheck disable=SC2034
2018-01-21 22:02:03 +00:00
local color_warning = "\\x1b[33m"
2016-12-01 13:40:56 +00:00
# shellcheck disable=SC2034
2018-01-21 22:02:03 +00:00
local color_error = "\\x1b[31m"
2016-12-01 13:40:56 +00:00
# shellcheck disable=SC2034
2018-01-21 22:02:03 +00:00
local color_critical = "\\x1b[1;31m"
2016-12-01 13:40:56 +00:00
# shellcheck disable=SC2034
2019-09-20 09:43:30 +00:00
local color_alert = "\\x1b[1;37;41m"
2016-12-01 13:40:56 +00:00
# shellcheck disable=SC2034
2019-09-20 09:43:30 +00:00
local color_emergency = "\\x1b[1;4;5;37;41m"
2016-12-01 13:40:56 +00:00
2016-11-08 12:03:26 +00:00
local colorvar = " color_ ${ log_level } "
2013-02-25 22:39:51 +00:00
2016-12-14 08:54:25 +00:00
local color = " ${ !colorvar :- ${ color_error } } "
2018-01-21 22:02:03 +00:00
local color_reset = "\\x1b[0m"
2016-11-08 12:03:26 +00:00
2019-09-20 09:30:59 +00:00
if [ [ " ${ NO_COLOR :- } " = "true" ] ] || { [ [ " ${ TERM :- } " != "xterm" * ] ] && [ [ " ${ TERM :- } " != "screen" * ] ] ; } || [ [ ! -t 2 ] ] ; then
2016-12-14 08:54:25 +00:00
if [ [ " ${ NO_COLOR :- } " != "false" ] ] ; then
2016-12-01 17:52:33 +00:00
# Don't use colors on pipes or non-recognized terminals
color = "" ; color_reset = ""
fi
2013-02-25 22:39:51 +00:00
fi
2016-11-08 12:03:26 +00:00
# all remaining arguments are to be printed
local log_line = ""
while IFS = $'\n' read -r log_line; do
2016-12-14 08:54:25 +00:00
echo -e " $( date -u +"%Y-%m-%d %H:%M:%S UTC" ) ${ color } $( printf "[%9s]" " ${ log_level } " ) ${ color_reset } ${ log_line } " 1>& 2
2016-11-08 12:03:26 +00:00
done <<< " ${ @ :- } "
2013-02-25 22:39:51 +00:00
}
2016-11-08 12:03:26 +00:00
2016-12-01 17:52:33 +00:00
function emergency ( ) { __b3bp_log emergency " ${ @ } " ; exit 1; }
2016-12-14 08:54:25 +00:00
function alert ( ) { [ [ " ${ LOG_LEVEL :- 0 } " -ge 1 ] ] && __b3bp_log alert " ${ @ } " ; true; }
function critical ( ) { [ [ " ${ LOG_LEVEL :- 0 } " -ge 2 ] ] && __b3bp_log critical " ${ @ } " ; true; }
function error ( ) { [ [ " ${ LOG_LEVEL :- 0 } " -ge 3 ] ] && __b3bp_log error " ${ @ } " ; true; }
function warning ( ) { [ [ " ${ LOG_LEVEL :- 0 } " -ge 4 ] ] && __b3bp_log warning " ${ @ } " ; true; }
function notice ( ) { [ [ " ${ LOG_LEVEL :- 0 } " -ge 5 ] ] && __b3bp_log notice " ${ @ } " ; true; }
function info ( ) { [ [ " ${ LOG_LEVEL :- 0 } " -ge 6 ] ] && __b3bp_log info " ${ @ } " ; true; }
function debug ( ) { [ [ " ${ LOG_LEVEL :- 0 } " -ge 7 ] ] && __b3bp_log debug " ${ @ } " ; true; }
2014-07-23 09:31:17 +00:00
2013-02-25 22:39:51 +00:00
function help ( ) {
2014-07-23 09:34:05 +00:00
echo "" 1>& 2
2016-12-01 13:40:56 +00:00
echo " ${ * } " 1>& 2
2014-07-23 09:34:05 +00:00
echo "" 1>& 2
2016-06-21 11:38:47 +00:00
echo " ${ __usage :- No usage available } " 1>& 2
2014-07-23 09:34:05 +00:00
echo "" 1>& 2
2016-11-08 12:02:37 +00:00
2016-12-14 08:54:25 +00:00
if [ [ " ${ __helptext :- } " ] ] ; then
2016-11-08 12:02:37 +00:00
echo " ${ __helptext } " 1>& 2
echo "" 1>& 2
fi
2013-02-25 22:39:51 +00:00
exit 1
}
### Parse commandline options
2016-06-21 11:49:11 +00:00
##############################################################################
# Commandline options. This defines the usage page, and is used to parse cli
# opts & defaults from. The parsing is unforgiving so be precise in your syntax
# - A short option must be preset for every long option; but every short option
# need not have a long option
# - `--` is respected as the separator between options and arguments
# - We do not bash-expand defaults, so setting '~/app' as a default will not resolve to ${HOME}.
# you can use bash variables to work around this (so use ${HOME} instead)
2016-12-01 13:40:56 +00:00
# shellcheck disable=SC2015
2016-12-14 08:54:25 +00:00
[ [ " ${ __usage +x } " ] ] || read -r -d '' __usage <<-'EOF' || true # exits non-zero when EOF encountered
2016-06-21 11:49:11 +00:00
-f --file [ arg] Filename to process. Required.
-t --temp [ arg] Location of tempfile. Default = "/tmp/bar"
-v Enable verbose mode, print script as it is executed
-d --debug Enables debug mode
-h --help This page
-n --no-color Disable color output
-1 --one Do just one thing
2019-09-20 09:40:06 +00:00
-i --input [ arg] File to process. Can be repeated.
-x Specify a flag. Can be repeated.
2016-06-21 11:49:11 +00:00
EOF
2016-12-01 13:40:56 +00:00
# shellcheck disable=SC2015
2016-12-14 08:54:25 +00:00
[ [ " ${ __helptext +x } " ] ] || read -r -d '' __helptext <<-'EOF' || true # exits non-zero when EOF encountered
2016-06-21 11:49:11 +00:00
This is Bash3 Boilerplate' s help text. Feel free to add any description of your
program or elaborate more on command-line arguments. This section is not
parsed and will be added as-is to the help.
EOF
2013-02-25 22:39:51 +00:00
# Translate usage string -> getopts arguments, and set $arg_<flag> defaults
2016-12-01 13:40:56 +00:00
while read -r __b3bp_tmp_line; do
2016-12-01 19:47:17 +00:00
if [ [ " ${ __b3bp_tmp_line } " = ~ ^- ] ] ; then
2016-11-11 00:13:28 +00:00
# fetch single character version of option string
2016-12-01 19:47:17 +00:00
__b3bp_tmp_opt = " ${ __b3bp_tmp_line %% * } "
__b3bp_tmp_opt = " ${ __b3bp_tmp_opt : 1 } "
2016-11-11 00:13:28 +00:00
# fetch long version if present
2016-12-01 19:47:17 +00:00
__b3bp_tmp_long_opt = ""
2016-12-14 08:54:25 +00:00
if [ [ " ${ __b3bp_tmp_line } " = *"--" * ] ] ; then
2016-12-01 19:47:17 +00:00
__b3bp_tmp_long_opt = " ${ __b3bp_tmp_line #*-- } "
__b3bp_tmp_long_opt = " ${ __b3bp_tmp_long_opt %% * } "
fi
2016-12-06 21:24:14 +00:00
# map opt long name to+from opt short name
printf -v " __b3bp_tmp_opt_long2short_ ${ __b3bp_tmp_long_opt //-/_ } " '%s' " ${ __b3bp_tmp_opt } "
printf -v " __b3bp_tmp_opt_short2long_ ${ __b3bp_tmp_opt } " '%s' " ${ __b3bp_tmp_long_opt //-/_ } "
2016-11-11 00:13:28 +00:00
# check if option takes an argument
2016-12-06 21:24:14 +00:00
if [ [ " ${ __b3bp_tmp_line } " = ~ \[ .*\] ] ] ; then
2016-11-11 00:13:28 +00:00
__b3bp_tmp_opt = " ${ __b3bp_tmp_opt } : " # add : if opt has arg
__b3bp_tmp_init = "" # it has an arg. init with ""
2016-12-05 21:52:22 +00:00
printf -v " __b3bp_tmp_has_arg_ ${ __b3bp_tmp_opt : 0 : 1 } " '%s' "1"
2016-12-06 21:24:14 +00:00
elif [ [ " ${ __b3bp_tmp_line } " = ~ \{ .*\} ] ] ; then
__b3bp_tmp_opt = " ${ __b3bp_tmp_opt } : " # add : if opt has arg
__b3bp_tmp_init = "" # it has an arg. init with ""
# remember that this option requires an argument
printf -v " __b3bp_tmp_has_arg_ ${ __b3bp_tmp_opt : 0 : 1 } " '%s' "2"
else
__b3bp_tmp_init = "0" # it's a flag. init with 0
printf -v " __b3bp_tmp_has_arg_ ${ __b3bp_tmp_opt : 0 : 1 } " '%s' "0"
2016-11-11 00:13:28 +00:00
fi
__b3bp_tmp_opts = " ${ __b3bp_tmp_opts :- } ${ __b3bp_tmp_opt } "
2019-09-20 09:40:06 +00:00
if [ [ " ${ __b3bp_tmp_line } " = ~ ^Can\ be\ repeated\. ] ] || [ [ " ${ __b3bp_tmp_line } " = ~ \. \ *Can\ be\ repeated\. ] ] ; then
# remember that this option can be repeated
printf -v " __b3bp_tmp_is_array_ ${ __b3bp_tmp_opt : 0 : 1 } " '%s' "1"
else
printf -v " __b3bp_tmp_is_array_ ${ __b3bp_tmp_opt : 0 : 1 } " '%s' "0"
fi
2013-02-25 22:39:51 +00:00
fi
2016-12-14 08:54:25 +00:00
[ [ " ${ __b3bp_tmp_opt :- } " ] ] || continue
2016-11-11 00:13:28 +00:00
2018-01-21 22:02:03 +00:00
if [ [ " ${ __b3bp_tmp_line } " = ~ ^Default= ] ] || [ [ " ${ __b3bp_tmp_line } " = ~ \. \ *Default= ] ] ; then
2016-11-11 00:13:28 +00:00
# ignore default value if option does not have an argument
__b3bp_tmp_varname = " __b3bp_tmp_has_arg_ ${ __b3bp_tmp_opt : 0 : 1 } "
2016-12-14 08:54:25 +00:00
if [ [ " ${ !__b3bp_tmp_varname } " != "0" ] ] ; then
2019-10-29 09:43:47 +00:00
# take default
2016-12-01 19:47:17 +00:00
__b3bp_tmp_init = " ${ __b3bp_tmp_line ##*Default= } "
2019-10-29 09:43:47 +00:00
# strip double quotes from default argument
2016-12-05 21:52:22 +00:00
__b3bp_tmp_re = '^"(.*)"$'
if [ [ " ${ __b3bp_tmp_init } " = ~ ${ __b3bp_tmp_re } ] ] ; then
__b3bp_tmp_init = " ${ BASH_REMATCH [1] } "
else
2019-10-29 09:43:47 +00:00
# strip single quotes from default argument
2016-12-05 21:52:22 +00:00
__b3bp_tmp_re = " ^'(.*)' $"
if [ [ " ${ __b3bp_tmp_init } " = ~ ${ __b3bp_tmp_re } ] ] ; then
2017-02-10 14:03:07 +00:00
__b3bp_tmp_init = " ${ BASH_REMATCH [1] } "
fi
2016-12-05 21:52:22 +00:00
fi
2016-11-11 00:13:28 +00:00
fi
2013-02-25 22:39:51 +00:00
fi
2016-11-11 00:13:28 +00:00
2018-01-21 22:02:03 +00:00
if [ [ " ${ __b3bp_tmp_line } " = ~ ^Required\. ] ] || [ [ " ${ __b3bp_tmp_line } " = ~ \. \ *Required\. ] ] ; then
2016-12-06 21:24:14 +00:00
# remember that this option requires an argument
printf -v " __b3bp_tmp_has_arg_ ${ __b3bp_tmp_opt : 0 : 1 } " '%s' "2"
fi
2019-10-29 09:43:47 +00:00
# Init var with value unless it is an array / a repeatable
2019-09-20 09:40:06 +00:00
__b3bp_tmp_varname = " __b3bp_tmp_is_array_ ${ __b3bp_tmp_opt : 0 : 1 } "
[ [ " ${ !__b3bp_tmp_varname } " = "0" ] ] && printf -v " arg_ ${ __b3bp_tmp_opt : 0 : 1 } " '%s' " ${ __b3bp_tmp_init } "
2016-11-08 12:02:37 +00:00
done <<< " ${ __usage :- } "
# run getopts only if options were specified in __usage
2016-12-14 08:54:25 +00:00
if [ [ " ${ __b3bp_tmp_opts :- } " ] ] ; then
2016-11-08 12:02:37 +00:00
# Allow long options like --this
__b3bp_tmp_opts = " ${ __b3bp_tmp_opts } -: "
# Reset in case getopts has been used previously in the shell.
OPTIND = 1
# start parsing command line
set +o nounset # unexpected arguments will cause unbound variables
2017-02-10 14:03:07 +00:00
# to be dereferenced
2016-11-08 12:02:37 +00:00
# Overwrite $arg_<flag> defaults with the actual CLI options
while getopts " ${ __b3bp_tmp_opts } " __b3bp_tmp_opt; do
2016-12-14 08:54:25 +00:00
[ [ " ${ __b3bp_tmp_opt } " = "?" ] ] && help " Invalid use of script: ${ * } "
2016-11-08 12:02:37 +00:00
2016-12-14 08:54:25 +00:00
if [ [ " ${ __b3bp_tmp_opt } " = "-" ] ] ; then
2016-11-08 12:02:37 +00:00
# OPTARG is long-option-name or long-option=value
if [ [ " ${ OPTARG } " = ~ .*= .* ] ] ; then
2017-02-10 14:03:07 +00:00
# --key=value format
__b3bp_tmp_long_opt = ${ OPTARG /=*/ }
# Set opt to the short option corresponding to the long option
__b3bp_tmp_varname = " __b3bp_tmp_opt_long2short_ ${ __b3bp_tmp_long_opt //-/_ } "
printf -v "__b3bp_tmp_opt" '%s' " ${ !__b3bp_tmp_varname } "
OPTARG = ${ OPTARG #*= }
2016-11-08 12:02:37 +00:00
else
2017-02-10 14:03:07 +00:00
# --key value format
# Map long name to short version of option
__b3bp_tmp_varname = " __b3bp_tmp_opt_long2short_ ${ OPTARG //-/_ } "
printf -v "__b3bp_tmp_opt" '%s' " ${ !__b3bp_tmp_varname } "
# Only assign OPTARG if option takes an argument
__b3bp_tmp_varname = " __b3bp_tmp_has_arg_ ${ __b3bp_tmp_opt } "
2018-09-03 10:00:55 +00:00
__b3bp_tmp_varvalue = " ${ !__b3bp_tmp_varname } "
[ [ " ${ __b3bp_tmp_varvalue } " != "0" ] ] && __b3bp_tmp_varvalue = "1"
printf -v "OPTARG" '%s' " ${ @ : OPTIND : ${ __b3bp_tmp_varvalue } } "
2017-02-10 14:03:07 +00:00
# shift over the argument if argument is expected
2018-09-03 10:00:55 +00:00
( ( OPTIND += __b3bp_tmp_varvalue) )
2016-11-08 12:02:37 +00:00
fi
# we have set opt/OPTARG to the short value and the argument as OPTARG if it exists
2016-02-16 03:06:32 +00:00
fi
2013-02-25 22:39:51 +00:00
2016-11-08 12:02:37 +00:00
__b3bp_tmp_value = " ${ OPTARG } "
2016-02-16 20:59:38 +00:00
2019-09-20 09:40:06 +00:00
__b3bp_tmp_varname = " __b3bp_tmp_is_array_ ${ __b3bp_tmp_opt : 0 : 1 } "
if [ [ " ${ !__b3bp_tmp_varname } " != "0" ] ] ; then
2019-10-29 09:43:47 +00:00
# repeatables
2019-09-20 09:40:06 +00:00
# shellcheck disable=SC2016
2019-10-29 09:43:47 +00:00
if [ [ -z " ${ OPTARG } " ] ] ; then
# repeatable flags, they increcemnt
__b3bp_tmp_varname = " arg_ ${ __b3bp_tmp_opt : 0 : 1 } "
debug " cli arg ${ __b3bp_tmp_varname } = ( ${ __b3bp_tmp_default } ) -> ${ !__b3bp_tmp_varname } "
2020-11-23 18:56:46 +00:00
# shellcheck disable=SC2004
2019-10-29 09:43:47 +00:00
__b3bp_tmp_value = $(( ${ !__b3bp_tmp_varname } + 1 ))
printf -v " ${ __b3bp_tmp_varname } " '%s' " ${ __b3bp_tmp_value } "
else
# repeatable args, they get appended to an array
__b3bp_tmp_varname = " arg_ ${ __b3bp_tmp_opt : 0 : 1 } [@] "
debug " cli arg ${ __b3bp_tmp_varname } append ${ __b3bp_tmp_value } "
declare -a " ${ __b3bp_tmp_varname } " = '("${!__b3bp_tmp_varname}" "${__b3bp_tmp_value}")'
fi
2019-09-20 09:40:06 +00:00
else
2019-10-29 09:43:47 +00:00
# non-repeatables
2019-09-20 09:40:06 +00:00
__b3bp_tmp_varname = " arg_ ${ __b3bp_tmp_opt : 0 : 1 } "
__b3bp_tmp_default = " ${ !__b3bp_tmp_varname } "
if [ [ -z " ${ OPTARG } " ] ] ; then
__b3bp_tmp_value = $(( __b3bp_tmp_default + 1 ))
fi
printf -v " ${ __b3bp_tmp_varname } " '%s' " ${ __b3bp_tmp_value } "
2019-10-29 09:43:47 +00:00
2019-09-20 09:40:06 +00:00
debug " cli arg ${ __b3bp_tmp_varname } = ( ${ __b3bp_tmp_default } ) -> ${ !__b3bp_tmp_varname } "
fi
2016-11-08 12:02:37 +00:00
done
set -o nounset # no more unbound variable references expected
2013-02-25 22:39:51 +00:00
2016-11-08 12:02:37 +00:00
shift $(( OPTIND-1))
2017-02-10 14:03:07 +00:00
if [ [ " ${ 1 :- } " = "--" ] ] ; then
shift
fi
2016-11-08 12:02:37 +00:00
fi
2016-12-06 21:24:14 +00:00
### Automatic validation of required option arguments
##############################################################################
for __b3bp_tmp_varname in ${ !__b3bp_tmp_has_arg_* } ; do
# validate only options which required an argument
2016-12-14 08:54:25 +00:00
[ [ " ${ !__b3bp_tmp_varname } " = "2" ] ] || continue
2016-12-06 21:24:14 +00:00
__b3bp_tmp_opt_short = " ${ __b3bp_tmp_varname ##*_ } "
__b3bp_tmp_varname = " arg_ ${ __b3bp_tmp_opt_short } "
2016-12-14 08:54:25 +00:00
[ [ " ${ !__b3bp_tmp_varname } " ] ] && continue
2016-12-06 21:24:14 +00:00
__b3bp_tmp_varname = " __b3bp_tmp_opt_short2long_ ${ __b3bp_tmp_opt_short } "
printf -v "__b3bp_tmp_opt_long" '%s' " ${ !__b3bp_tmp_varname } "
2016-12-14 08:54:25 +00:00
[ [ " ${ __b3bp_tmp_opt_long :- } " ] ] && __b3bp_tmp_opt_long = " (-- ${ __b3bp_tmp_opt_long //_/- } ) "
2016-12-06 21:24:14 +00:00
help " Option - ${ __b3bp_tmp_opt_short } ${ __b3bp_tmp_opt_long :- } requires an argument "
done
2016-11-08 12:02:37 +00:00
### Cleanup Environment variables
##############################################################################
for __tmp_varname in ${ !__b3bp_tmp_* } ; do
2016-12-05 21:52:22 +00:00
unset -v " ${ __tmp_varname } "
2016-11-08 12:02:37 +00:00
done
2013-02-25 22:39:51 +00:00
2016-12-05 21:52:22 +00:00
unset -v __tmp_varname
2013-02-25 22:39:51 +00:00
2016-11-09 09:03:00 +00:00
### Externally supplied __usage. Nothing else to do here
##############################################################################
2016-12-14 08:54:25 +00:00
if [ [ " ${ __b3bp_external_usage :- } " = "true" ] ] ; then
2016-12-05 21:52:22 +00:00
unset -v __b3bp_external_usage
2016-11-09 09:03:00 +00:00
return
fi
2017-02-10 19:08:51 +00:00
2017-02-10 14:03:07 +00:00
### Signal trapping and backtracing
##############################################################################
function __b3bp_cleanup_before_exit ( ) {
info "Cleaning up. Done"
}
trap __b3bp_cleanup_before_exit EXIT
# requires `set -o errtrace`
__b3bp_err_report( ) {
2019-11-18 10:56:18 +00:00
local error_code = ${ ? }
2017-02-10 14:03:07 +00:00
error " Error in ${ __file } in function ${ 1 } on line ${ 2 } "
exit ${ error_code }
}
# Uncomment the following line for always providing an error backtrace
# trap '__b3bp_err_report "${FUNCNAME:-.}" ${LINENO}' ERR
2016-11-09 09:03:00 +00:00
2017-02-10 19:08:51 +00:00
2016-06-21 11:49:11 +00:00
### Command-line argument switches (like -d for debugmode, -h for showing helppage)
##############################################################################
2013-02-25 22:39:51 +00:00
# debug mode
2016-12-14 08:54:25 +00:00
if [ [ " ${ arg_d : ? } " = "1" ] ] ; then
2014-07-23 09:31:34 +00:00
set -o xtrace
2019-05-06 08:04:09 +00:00
PS4 = '+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
2013-02-25 22:39:51 +00:00
LOG_LEVEL = "7"
2017-02-10 14:03:07 +00:00
# Enable error backtracing
trap '__b3bp_err_report "${FUNCNAME:-.}" ${LINENO}' ERR
2013-02-25 22:39:51 +00:00
fi
2016-02-16 03:06:32 +00:00
# verbose mode
2016-12-14 08:54:25 +00:00
if [ [ " ${ arg_v : ? } " = "1" ] ] ; then
2016-02-16 03:06:32 +00:00
set -o verbose
fi
2016-06-19 11:06:53 +00:00
# no color mode
2016-12-14 08:54:25 +00:00
if [ [ " ${ arg_n : ? } " = "1" ] ] ; then
2016-06-19 11:06:53 +00:00
NO_COLOR = "true"
fi
2013-02-25 22:39:51 +00:00
# help mode
2016-12-14 08:54:25 +00:00
if [ [ " ${ arg_h : ? } " = "1" ] ] ; then
2013-02-26 12:12:53 +00:00
# Help exists with code 1
2013-02-25 22:39:51 +00:00
help " Help using ${ 0 } "
fi
2016-06-21 11:49:11 +00:00
### Validation. Error out if the things required for your script are not present
##############################################################################
2013-02-25 22:39:51 +00:00
2016-12-14 08:54:25 +00:00
[ [ " ${ arg_f :- } " ] ] || help "Setting a filename with -f or --file is required"
[ [ " ${ LOG_LEVEL :- } " ] ] || emergency "Cannot continue without LOG_LEVEL. "
2013-02-25 22:39:51 +00:00
### Runtime
2016-06-21 11:49:11 +00:00
##############################################################################
2013-02-25 22:39:51 +00:00
2017-02-10 19:08:51 +00:00
info " __i_am_main_script: ${ __i_am_main_script } "
2016-02-16 21:19:08 +00:00
info " __file: ${ __file } "
info " __dir: ${ __dir } "
info " __base: ${ __base } "
2016-06-24 11:12:41 +00:00
info " OSTYPE: ${ OSTYPE } "
2014-07-29 15:32:23 +00:00
2016-02-16 21:05:11 +00:00
info " arg_f: ${ arg_f } "
info " arg_d: ${ arg_d } "
info " arg_v: ${ arg_v } "
info " arg_h: ${ arg_h } "
2019-10-29 08:57:59 +00:00
# shellcheck disable=SC2015
if [ [ -n " ${ arg_i :- } " ] ] && declare -p arg_i 2> /dev/null | grep -q '^declare \-a' ; then
2019-10-29 09:43:47 +00:00
info "arg_i:"
2019-10-29 07:34:52 +00:00
for input_file in " ${ arg_i [@] } " ; do
2019-09-20 09:40:06 +00:00
info " - ${ input_file } "
done
2019-10-29 08:57:59 +00:00
elif [ [ -n " ${ arg_i :- } " ] ] ; then
info " arg_i: ${ arg_i } "
2019-09-20 09:40:06 +00:00
else
info "arg_i: 0"
fi
2019-10-29 08:57:59 +00:00
2019-09-20 09:40:06 +00:00
# shellcheck disable=SC2015
2019-10-29 08:57:59 +00:00
if [ [ -n " ${ arg_x :- } " ] ] && declare -p arg_x 2> /dev/null | grep -q '^declare \-a' ; then
info " arg_x: ${# arg_x [@] } "
elif [ [ -n " ${ arg_x :- } " ] ] ; then
info " arg_x: ${ arg_x } "
else
info "arg_x: 0"
fi
2016-02-16 21:05:11 +00:00
2018-01-21 22:02:03 +00:00
info " $( echo -e "multiple lines example - line #1\\nmultiple lines example - line #2\\nimagine logging the output of 'ls -al /path/'" ) "
2016-11-08 12:03:26 +00:00
2016-02-16 21:19:08 +00:00
# All of these go to STDERR, so you can use STDOUT for piping machine readable information to other software
2013-02-25 22:39:51 +00:00
debug "Info useful to developers for debugging the application, not useful during operations."
info "Normal operational messages - may be harvested for reporting, measuring throughput, etc. - no action required."
notice "Events that are unusual but not error conditions - might be summarized in an email to developers or admins to spot potential problems - no immediate action required."
2023-07-05 20:21:11 +00:00
warning "Warning messages, not an error, but indication that an error will occur if action is not taken, e.g. file system 85% full - each item must be resolved within a given time."
2013-02-25 22:39:51 +00:00
error "Non-urgent failures, these should be relayed to developers or admins; each item must be resolved within a given time."
critical "Should be corrected immediately, but indicates failure in a primary system, an example is a loss of a backup ISP connection."
alert "Should be corrected immediately, therefore notify staff who can fix the problem. An example would be the loss of a primary ISP connection."
emergency "A \"panic\" condition usually affecting multiple apps/servers/sites. At this level it would usually notify all tech staff on call."