Wiki
* Scroll me *
 PREFACE
  About Wiki
  GOLANG
  Snippets
   Pitfalls
   Development
   Production
  SHELL
  Shell Script
  NETWORKING
  Networking
  KUBERNETES
  Commands
   Patterns
   Potholes
  ISTIO
  Istio
  VAULT
  Vault
  INFRA AS CODE
  Terraform
   Pulumi
  Shell Script
Table of Contents
Robust Shell Scripts
First of all, if your script is over 100 lines, it should probably be rewritten in Python or Go.
Bash Options
Always do set -o errexit -o pipefail -o nounset at the start of the script.
-o errexit: Abort when a command exits with non-zero status (except in until, while, if)-o pipefail: Causes a pipeline to return the exit status of the last command in the pipe that returned a non-zero return value.-o nounset: Attempt to use undefined variable causes an error and forces an exit
Trapping Deferred Calls
1
2
3
trap '{
  rm -f '"${TEMP_FILE}" "${LOCK_FILE}"'
}' INT TERM EXIT
INT: capturing SIGINT (Interrupt). ctrl-c sends such a signal.TERM: capturing SIGTERM (Terminate).EXITis a pseudo-signal triggered when the script exits, either through reaching the end of the script, anexitcommand, or a failing command whenset -o errexit.
Just Quote Everything
Variable expansion:
- Good: 
"$my_var" - Bad: 
$my_var 
Command substitution:
- Good: 
"$(cmd)" - Bad: 
$(cmd) 
Linter and Formatter
- Use shellcheck, a shell script static analysis tool, to improve your script.
 - Use shfmt to format your script
 
Further Reading
Bash Pitfalls: a compilation of common mistakes made by bash users.
Snippets
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# log interpolates and writes message to stderr with timestamp.
log() {
  echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*" >&2
}
# Retry a command up to a specific numer of times until it exits successfully,
# with exponential back off.
#
#  $ retry 5 echo Hello
#  Hello
#
#  $ retry 5 false
#  Retry 1/5 "false" exited 1, retrying in 1 seconds...
#  Retry 2/5 "false" exited 1, retrying in 2 seconds...
#  Retry 3/5 "false" exited 1, retrying in 4 seconds...
#  Retry 4/5 "false" exited 1, retrying in 8 seconds...
#  Retry 5/5 "false" exited 1, no more retries left.
#
retry() {
	local retries=$1
	shift
	local count=0
	until "$@"; do
		exit=$?
		wait=$((2 ** count))
		count=$((count + 1))
		if [ $count -lt "$retries" ]; then
			log "Retry $count/$retries \"$*\" exited $exit, retrying in $wait seconds..."
			sleep $wait
		else
			log "Retry $count/$retries \"$*\" exited $exit, no more retries left."
			return $exit
		fi
	done
	return 0
}