Boost Your Bash Scripts: Safety, Functions, and Advanced Tips
This article presents practical Bash scripting techniques—including safety flags, function definitions, variable annotations, modern command substitution, double‑bracket tests, powerful string manipulation, process substitution, here‑documents, built‑in variables, and debugging methods—to write more reliable and maintainable shell scripts.
Script Safety
Start every Bash script with strict error handling to avoid common pitfalls:
#!/bin/bash
set -o nounset # Treat unset variables as an error
set -o errexit # Exit immediately on command failureThese options prevent using undefined variables and silently ignoring failed commands, though some commands (e.g., mkdir -p, rm -f) can still suppress errors, and errexit may not catch every failure.
Script Functions
Define reusable functions to improve readability and modularity. Example of extracting comments:
ExtractBashComments(){ egrep "^#" }
cat myscript.sh | ExtractBashComments | wc
comments=$(ExtractBashComments < myscript.sh)Other examples show summing lines and logging:
SumLines(){
local sum=0 line=""
while read line; do
sum=$((sum + line))
done
echo $sum
}
log(){
local prefix="[$(date +"%Y/%m/%d %H:%M:%S")]: "
echo "${prefix}$@" >&2
}
log "INFO" "a message"Keep most code inside functions; only global variables, constants, and the final call to main should remain at the top level.
Variable Annotations
Use local for function‑scoped variables and readonly for constants. Example:
# Define a default that can be overridden
readonly DEFAULT_VAL=${DEFAULT_VAL:-7}
myfunc(){
local some_var=${DEFAULT_VAL}
# ...
}Attempting to modify a readonly variable triggers an error:
x=5
x=6
readonly x
x=7 # failureAnnotate all script variables with local or readonly whenever possible.
Modern Command Substitution
Prefer $(...) over backticks because it nests cleanly and avoids escaping issues. Example:
echo "A-$(echo B-$(echo C-$(echo D)))"Double Brackets [[ ]] vs Single Brackets [ ]
Use [[ ... ]] for safer tests, pattern matching, and extended syntax. Examples:
# Single brackets (traditional)
[ "${name}" > "a" -o ${name} < "m" ]
# Double brackets (preferred)
[[ "${name}" > "a" && "${name}" < "m" ]]
# Globbing and regex examples
[[ "$t" == abc* ]] # globbing (true)
[[ "$t" =~ abc[0-9]+ ]] # regex (true)Note: From Bash 3.2 onward, quoting the pattern disables globbing and regex evaluation; store complex patterns in variables if they contain spaces.
String Operations
Bash provides length, slicing, replacement, and deletion operators:
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"
pos=6; len=5; slice4=${f:${pos}:${len}} # "path2"
# Replacement
single_subst=${f/path?/x} # "x/path2/file.ext"
global_subst=${f//path?/x} # "x/x/file.ext"
# Deletion (globbing)
extension=${f#*.} # "ext"
filename=${f##*/} # "file.ext"
dirname=${f%/*} # "path1/path2"
root=${f%%/*} # "path1"Avoid Temporary Files
Use process substitution <( ... ) to feed command output where a filename is required:
# Compare two web pages without creating temp files
bash -c "diff <(wget -O - url1) <(wget -O - url2)"Here Documents
Embed multi‑line strings directly into a script:
command << MARKER
...${var}
$(cmd)...
MARKERQuote the delimiter to suppress variable expansion:
command <<'MARKER'
no substitution here
MARKERBuilt‑in Variables
Key points: use $@ (quoted) instead of $* for proper handling of arguments containing spaces.
Debugging
Syntax check: bash -n myscript.sh Trace execution:
bash -v myscript.sh # verbose
bash -x myscript.sh # execution traceSet these options permanently at the script top with set -o verbose and set -o xtrace, useful for remote execution.
When Not to Use Bash
Your script grows to hundreds of lines.
You need complex data structures beyond arrays.
Escaping becomes overly complicated.
Heavy string manipulation dominates.
Little interaction with other programs or pipelines.
Performance concerns arise.
In such cases, consider a higher‑level language like Python or Ruby.
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.
ITPUB
Official ITPUB account sharing technical insights, community news, and exciting events.
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.
