Master Clean Shell Scripts: Proven Practices for Readable, Efficient Bash Code
This article compiles essential shell‑script guidelines—shebang usage, commenting, parameter validation, variable handling, indentation, naming conventions, encoding, permissions, logging, security, line continuation, quoting, modular main functions, scope control, return values, indirect references, heredocs, path resolution, brevity, parallel execution, and search tricks—to help you write maintainable and performant Bash scripts.
Because of work requirements I recently revisited shell scripting. Although I use most commands daily, my scripts often look messy and are hard to read, especially when compared with others' scripts. Shell scripts are more like toolchains than formal programming languages, so many people write them ad‑hoc, resulting in long, unstructured code.
After consulting various documents I gathered scattered advice into a concise technical specification for my future scripts.
Shebang
The shebang ("#!") on the first line specifies the interpreter when none is given. Common examples: #!/bin/bash You can list supported interpreters with:
$ cat /etc/shells
/bin/sh
/bin/dash
/bin/bash
/rbash
/usr/bin/screenRunning ./a.sh without a shebang uses $SHELL. A portable shebang is recommended: #!/usr/bin/env bash Code Comments
Comments are crucial in shell scripts to explain purpose, parameters, usage, warnings, author info, and function details.
shebang
脚本的参数
脚本的用途
脚本的注意事项
脚本的写作时间,作者,版权等
各个函数前的说明注释
一些较复杂的单行命令注释Parameter Validation
Always check that arguments meet expectations and provide clear feedback:
if [[ $# != 2 ]]; then
echo "Parameter incorrect."
exit 1
fiVariables and Magic Numbers
Define important environment variables at the top and avoid hard‑coded magic numbers. Example for Java version control:
source /etc/profile
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/apps/bin/"Use variables instead of literals so changes are easy.
Indentation Rules
Consistent indentation (soft tabs with 2 or 4 spaces, or hard tabs) improves readability, especially in functions and control structures.
Soft tab: n spaces (commonly 2 or 4)
Hard tab: literal "\t" character
Naming Conventions
Follow these standards:
File names end with .sh Variable names are meaningful and correctly spelled
Use lowercase with underscores for identifiers
Encoding
Write scripts in UTF‑8 without BOM. Use English for comments and logs to avoid encoding issues on different machines. When editing on Windows, ensure the file is saved as UTF‑8 without BOM.
Permissions
Remember to make scripts executable (e.g., chmod +x script.sh).
Logging and Echo
Logging aids debugging; real‑time echo helps users track progress. ANSI/VT100 sequences can add colors or effects.
Never Hard‑Code Passwords
Never embed passwords in scripts, especially when the code is stored in public repositories.
Line Continuation
Break long commands with a backslash and a preceding space:
./configure \
--prefix=/usr \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.confNote the space before the backslash.
Efficiency Matters
Choose commands that minimize work. Example: sed -n '1p;1q' file reads only the first line, unlike sed -n '1p' file.
Always Quote Variables
Wrap variable expansions in double quotes to prevent word splitting and globbing:
#!/bin/sh
var="*.sh"
echo $var # expands to file list
echo "$var" # prints literal *.shUse a Main Function
Structure scripts with functions and a main entry point for clarity:
#!/usr/bin/env bash
func1() { :; }
func2() { :; }
main() {
func1
func2
}
main "$@"Scope Considerations
Variables are global by default. Prefer local readonly or declare inside functions to limit scope.
Function Return Values
Functions return integer status codes (0 for success). To return strings, echo the value and capture it:
func() { echo "2333"; }
res=$(func)
echo "This is from $res."Indirect Variable Reference
Use ${!VAR} to retrieve the value of a variable whose name is stored in another variable.
VAR1="value"
VAR2="VAR1"
echo ${!VAR2} # prints "value"Heredocs
Heredocs simplify creating multi‑line files:
cat >> /etc/rsyncd.conf <<EOF
log file = /usr/local/logs/rsyncd.log
transfer logging = yes
log format = %t %a %m %f %b
syslog facility = local3
EOFFinding Script Directory
Use reliable methods to obtain the script’s own path:
script_dir=$(cd $(dirname $0) && pwd)
# or
script_dir=$(dirname $(readlink -f $0))Keep Code Short
Prefer a single command over pipelines when possible, e.g., grep root /etc/passwd instead of cat /etc/passwd | grep root. Combining multiple sed expressions into one command also improves speed.
Command Parallelization
Run functions in background and wait for them, or use xargs -P for parallel execution:
for ((i=0;i<10;i++)); do
func &
done
waitFull‑Text Search
When searching files, handle spaces in filenames and binary files correctly:
find . -type f -name '*.txt' -print0 | xargs -0 grep -a 2333Adopt New Syntax
Define functions as func(){} instead of func{} Use [[ ]] for tests
Prefer $(...) over backticks for command substitution
Use printf instead of echo for complex output
Other Tips
Prefer absolute paths; if using relative paths, prefix with ./ Prefer Bash parameter expansion over awk / sed for simple tasks
Write simple if statements on one line using && and || Namespace exported variables to avoid collisions
Use trap to handle termination signals
Create temporary files with mktemp Redirect unwanted output to /dev/null Check command exit status to detect failures
Test file existence before operating on it
Avoid parsing ls output
Read files with while read loops instead of for When copying directories, ensure the destination exists or use cp -r appropriately
Source: https://blog.mythsman.com/post/5d2ab67ff678ba2eb3bd346f/
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.
