Mastering Shell Script Style: Essential Guidelines for Clean, Efficient Bash Code
This article compiles practical shell‑script coding standards—covering shebang usage, commenting, parameter validation, variable handling, indentation, naming, encoding, logging, security, modular design, parallel execution, and static analysis with shellcheck—to help developers write readable, maintainable, and performant Bash scripts.
Preface
Due to work requirements the author revisited shell scripting. Although most commands are familiar, scripts often look messy and hard to read. Shell scripts are more a tool than a full programming language, mixing various programs for convenience.
Code Style Guidelines
Shebang
The shebang (#!) on the first line specifies the interpreter when none is given explicitly. Example: #!/bin/bash To list supported interpreters on the host:
cat /etc/shells
#/etc/shells: valid login shells
/bin/sh
/bin/dash
/bin/bash
/bin/rbash
/usr/bin/screenWhen executing a script without a shebang, the $SHELL variable determines the interpreter; otherwise the shebang takes precedence. Using a shebang is the recommended practice.
Comments
Comments are essential in shell scripts because many one‑liner commands are not self‑explanatory. A good comment acts like a README, describing purpose, parameters, usage, caveats, author, timestamps, and licensing. Typical comment sections include:
Shebang
Script parameters
Purpose
Precautions
Author, date, license
Function descriptions
Complex one‑liner explanations
Parameter Validation
Validate the number and format of parameters before proceeding. Example:
if [[ $# != 2 ]]; then
echo "Parameter incorrect."
exit 1
fiVariables and Magic Numbers
Define important environment variables at the script top and avoid hard‑coded magic numbers. For example, when managing multiple Java versions, set JAVA_HOME and adjust PATH explicitly.
source /etc/profile
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/apps/bin/"Indentation
Consistent indentation (soft tabs with 2 or 4 spaces, or hard tabs) improves readability, especially inside functions and control structures.
Soft tab: use spaces
Hard tab: use the literal \t character
Naming Conventions
File names end with .sh
Variable names are meaningful, lowercase with underscores
Encoding
Prefer UTF‑8 without BOM. When editing on Windows, ensure the file is saved as UTF‑8 without BOM to avoid stray characters on Linux. Also handle line‑ending differences (CRLF vs LF) using tools like dos2unix or unix2dos.
Permissions
Remember to set executable permission (e.g., chmod +x script.sh) so the script can be run directly.
Logging and Echo
Use logging for debugging and user feedback. Prefer printf over echo for complex output, and consider ANSI color codes for better UX.
Security
Never hard‑code passwords in scripts; keep secrets out of version control.
Line Continuation
Break long commands with a backslash (\) for readability, ensuring a space precedes the backslash.
./configure \
--prefix=/usr \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.confAdvanced Tips
Use source /etc/profile and export variables wisely.
Prefer [[ ... ]] over [ ... ] for tests.
Capture command output with $(...) instead of backticks.
Wrap multi‑line text with heredocs ( <<EOF).
Determine script directory reliably:
script_dir=$(cd $(dirname $0) && pwd)
script_dir=$(dirname $(readlink -f $0))Efficiency
Choose commands that minimize I/O. For example, head -n1 file is faster than sed -n '1p' file. Combine multiple sed expressions into a single invocation, and use xargs -P $(nproc) for parallel processing.
find . -name '*.txt' | xargs -P $(nproc) sed -i "s/233/666/g;s/235/626/g;s/333/616/g;s/233/664/g"Parallel Execution
Simple parallelism can be achieved with background jobs ( &) and wait. For more control, use parallel or xargs -P.
func(){
# do something
}
for ((i=0;i<10;i++)); do
func &
done
waitFull‑text Search
When searching across many files, handle spaces in filenames and binary files correctly:
find . -type f -print0 | xargs -0 grep -a 'search_term'Static Analysis with ShellCheck
ShellCheck is a widely used open‑source static analysis tool for shell scripts. It integrates with many package managers, CI systems (e.g., Travis CI), and provides detailed explanations for each warning, helping developers write safer scripts.
Other Small Tips
Prefer absolute paths; if using relative paths, prefix with ./.
Use Bash variable substitution instead of external tools like awk or sed when possible.
Write simple conditionals on a single line with && and ||.
Export variables with a namespace to avoid clashes.
Use trap to handle termination signals.
Create temporary files with mktemp.
Redirect unwanted output to /dev/null.
Check file existence before operating on it.
Avoid parsing ls output; use globbing or find instead.
Read files with while read loops rather than for over $(cat).
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.
Open Source Linux
Focused on sharing Linux/Unix content, covering fundamentals, system development, network programming, automation/operations, cloud computing, and related professional knowledge.
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.
