Skip to content

Instantly share code, notes, and snippets.

@Segmentational
Last active June 29, 2025 10:16
Show Gist options
  • Save Segmentational/08c1a7a0b39669f353db8285dffff33d to your computer and use it in GitHub Desktop.
Save Segmentational/08c1a7a0b39669f353db8285dffff33d to your computer and use it in GitHub Desktop.
Bash-Template-Example.bash
#!/usr/bin/env bash
# -*- Coding: UTF-8 -*- #
# -*- System: Linux -*- #
# -*- Usage: *.* -*- #
#
# General Bash Template
#
#
# Shellcheck Ignore List
#
# shellcheck disable=SC1073
# shellcheck disable=SC2120
# shellcheck disable=SC2071
# shellcheck disable=SC2086
#
#
# See Bash Set-Options Reference Below
#
set -o pipefail
set -o errexit
set -o xtrace
# Ensures a given amount of arguments is satisfied, otherwise logs a validation-related
# error, the expected number of arguments, and caller information. Usage is intended to
# be limited to other functions; calls to "validate" should never come from the global
# namespace.
#
# Arguments:
# - (1): The total number of expected arguments.
# - (2-n): The remaining arguments. Typically this value should be "${#}" without quoting.
#
# Example Usage:
# function example() {
# validate 2 ${#} || echo "Expected Argument(s) (1) (2) ..." > /dev/stderr
# return 1
# }
function validate() {
[[ (( ${#FUNCNAME[*]} == 0 )) ]] && echo -e "Fatal Error - Cannot Call \"${FUNCNAME[0]}\" || \"${FUNCNAME[1]}\" From Global Namespace" > /dev/stderr && return 1
echo "[Debug] (${FUNCNAME[1]}) Evaluating Input. Arguments-Count: (${#})" > /dev/stderr
if ! [[ ${#} -eq 2 ]]; then
echo "[Error] (${FUNCNAME[0]}) Invalid Arguments Received. Caller: \"${FUNCNAME[1]}\". Expected Total Arguments Required (1), and Total Caller Arguments (2)" > /dev/stderr
return 1
fi
return 0
}
# Unsets authentication-related aws environment variables; caution usage
# in dynamic environments such as IMDSv2 capable systems.
function unset-aws-environment-variables() {
unset AWS_ACCESS_KEY_ID
unset AWS_SECRET_ACCESS_KEY
unset AWS_SESSION_TOKEN
unset AWS_PROFILE
unset AWS_DEFAULT_PROFILE
}
# Creates an async worker. Requires a name argument (1).
#
# NOTE: Do not use a "-" or " " separated value for the (1) argument.
#
# A coprocess is executed asynchronously in a subshell, as if the command had been terminated
# with the ‘&’ control operator, with a two-way pipe established between the executing shell
# and the coprocess.
#
# Call "wait" to wait for all background jobs to complete.
#
# - https://www.gnu.org/software/bash/manual/html_node/Coprocesses.html
function worker() {
validate 1 ${#} || echo "[Error] (${FUNCNAME[0]}) Invalid Arguments Received. Expected Worker-Name (1)" > /dev/stderr
[[ -z "${1}" ]] && echo "[Error] (${FUNCNAME[0]}) Invalid Worker-Name (1). Caller: \"${FUNCNAME[1]}\"" > /dev/stderr && return 1
declare name="${1}"
# Start a named coprocess "${1}" running the "sleep" command following "echo".
coproc "${name}" {
echo "(${name}) Started ..."
sleep 5
echo "(${name}) Complete ..."
}
}
function require() {
for executable in "${@}"; do
declare name="${executable}"
if [[ -z $(command -v "${name}") ]]; then
echo "[Error] (${FUNCNAME[0]}) Command Not Found. Target: \"${name}\"" > /dev/stderr
return 1
fi
done
}
function main() {
echo "[Log] (${FUNCNAME[0]}) ..." > /dev/stderr
worker "testing"
wait
}
require "jq" "kubectl" "go" "xcode-select" "git"
main
# 1. set -o verbose ::: Print shell input upon read.
# 2. set -o allexport ::: Export all variable(s) + function(s) to environment.
# 3. set -o errexit ::: Exit immediately upon pipeline'd failure.
# 4. set -o monitor ::: Output process-separated command(s).
# 5. set -o privileged ::: Ignore externals - ensures of pristine run environment.
# 6. set -o xtrace ::: Print a trace of simple commands.
# 7. set -o braceexpand ::: Enable brace expansion. Enabled by default.
# 8. set -o no-exec ::: Bash syntax debugging; reads in commands but does not execute them.
# 9. set -o pipefail ::: Ensures the pipeline return value is that of the last command to exit.
# 10. set -o history ::: Enable the use of history for the given script.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment