Master Bash Scripting: Safety, Functions, and Best Practices
This article presents a comprehensive guide to writing robust Bash scripts, covering safety options, function definitions, variable annotations, modern syntax like $() and [[ ]], string manipulation techniques, built‑in variables, debugging methods, and recommendations on when to avoid Bash in favor of other languages.
Script Safety
Start every Bash script with these options to prevent common errors:
#!/bin/bash
set -o nounset
set -o errexitThis avoids referencing undefined variables and silently ignoring failed commands. Note that some commands (e.g., mkdir -p, rm -f) can force error suppression, and errexit does not catch every failure.
Script Functions
Define reusable functions to improve readability. Example:
ExtractBashComments() {
egrep "^#"
}
cat myscript.sh | ExtractBashComments | wc
comments=$(ExtractBashComments < myscript.sh)Additional examples:
SumLines() {
# iterating over stdin - similar to awk
local sum=0
local line=""
while read line; do
sum=$((sum + line))
done
echo $sum
}
SumLines < data_one_number_per_line.txt
log() {
# classic logger
local prefix="[$(date +%Y/%m/%d %H:%M:%S)]: "
echo "${prefix}$@" >&2
}
log "INFO" "a message"Place only global variables, constants, and the call to main at the top level.
Variable Annotations
Use local for function‑scoped variables and readonly for constants. Example:
# a useful idiom: DEFAULT_VAL can be overwritten
# with an environment variable of the same name
readonly DEFAULT_VAL=${DEFAULT_VAL:-7}
myfunc() {
# initialize a local variable with the global default
local some_var=${DEFAULT_VAL}
...
}Convert a mutable variable to read‑only:
x=5
x=6
readonly x
x=7 # failurePrefer annotating all variables with local or readonly.
Use $() Instead of Backticks
$()is clearer and nestable:
# both commands below print out: A-B-C-D
echo "A-`echo B-\`echo C-\\\`echo D\\\`\`"
echo "A-$(echo B-$(echo C-$(echo D)))"Prefer [[ ]] Over [ ]
Double brackets provide logical operators, string/regex comparisons, and avoid many quoting issues. Examples:
# single brackets
[ "${name}" > "a" -o ${name} < "m" ]
# double brackets
[[ "${name}" > "a" && "${name}" < "m" ]]Regular Expressions / Globbing
Double brackets enable globbing and regex matching:
t="abc123"
[[ "$t" == abc* ]] # true (globbing)
[[ "$t" == "abc*" ]] # false (literal)
[[ "$t" =~ [abc]+[123]+ ]] # true (regex)From Bash 3.2 onward, regexes should not be quoted. Store complex patterns in variables if they contain spaces.
String Operations
Various ways to manipulate strings, including length, slicing, substitution, and removal:
f="path1/path2/file.ext"
len="${#f}" # length = 20
slice1="${f:6}" # "path2/file.ext"
slice2="${f:6:5}" # "path2"
slice3="${f: -8}" # "file.ext"
slice4="${f:${pos}:${len}}" # using variables
# substitution
single_subst="${f/path?/x}" # "x/path2/file.ext"
global_subst="${f//path?/x}" # "x/x/file.ext"
# delete prefix/suffix
extension="${f#*.}" # "ext"
filename="${f##*/}" # "file.ext"
dirname="${f%/*}" # "path1/path2"
root="${f%%/*}" # "path1"Avoid Temporary Files
Use process substitution and here‑documents when a command expects a filename:
# compare two web pages without temporary files
diff <(wget -O - url1) <(wget -O - url2)Here‑document example:
command << MARKER
...${var}...
$(cmd)
MARKERBuilt‑in Variables
Common special variables:
$0 – script name
$n – nth argument
$$ – script PID
$! – PID of last background command
$? – exit status of last command
$# – number of arguments
$@ – all arguments as separate words
$* – all arguments as a single word (rarely useful)
Prefer $@ with quotes to preserve spacing.
Debugging
Syntax check: bash -n myscript.sh Verbose execution: bash -v myscript.sh Execution tracing with expanded info: bash -x myscript.sh Use set -o verbose and set -o xtrace in the script header for permanent tracing, especially on remote machines.
When Not to Use Bash
Avoid Bash for scripts that are very long, require complex data structures, involve intricate escaping, perform heavy string manipulation, have minimal interaction with other programs, or need high performance. In such cases consider languages like Python or Ruby.
References
Advanced Bash‑Scripting Guide: http://tldp.org/LDP/abs/html/
Bash Reference Manual
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
MaGe Linux Operations
Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
