chatgpt
Excellent — let’s write what I’d call the “Bash Survival Guide for Python Programmers.”
It’s structured as a practical cheat sheet, not a tutorial — to be read and used like a checklist when writing scripts.
🧠 Bash Survival Guide for Python Programmers
1. Start Every Script Strictly
Always begin with:
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
Explanation:
-
-e
— aborts script on any error -
-u
— aborts on undefined variables -
-o pipefail
— failures in a pipeline aren’t ignored -
IFS=$'\n\t'
— prevents word-splitting on spaces
This combination brings Bash’s behavior closer to Python’s sanity.
2. Quoting: Always, Always Quote Variables
Unquoted variables cause word splitting and glob expansion.
Always do this:
✅ Good
echo "$file"
rm -- "$filename"
grep "$pattern" "$file"
🚫 Bad
echo $file
rm $filename
grep $pattern $file
Rule: Quote every variable unless you are 100% sure you need splitting.
3. Prefer [[ ... ]]
over [ ... ]
[[ ... ]]
is Bash’s improved conditional syntax:
-
No need to quote variables (safe with empty strings)
-
Supports regex (
=~
) -
Logical operators
&&
,||
work inside
✅ Good
if [[ -f "$file" && $count -lt 10 ]]; thenecho "ok"
fi
🚫 Bad
if [ -f $file -a $count -lt 10 ]; thenecho "ok"
fi
4. Use (( ... ))
for Arithmetic
No $
needed inside; arithmetic only, no strings.
✅ Good
if (( count < 10 )); then((count++))
fi
🚫 Bad
if [ $count -lt 10 ]; thencount=$((count+1))
fi
5. Use Arrays for Lists
Bash arrays are clunky, but necessary to handle filenames and arguments safely.
files=(file1.txt "file with spaces.txt" file3.txt)for f in "${files[@]}"; doecho "$f"
done
Never iterate like this:
for f in $files; do ... # breaks on spaces
6. Command Substitution
Prefer modern syntax:
output=$(command arg)
over the ancient:
output=`command arg`
And never forget to quote expansions:
echo "$output"
7. Test Files Explicitly
Test | Meaning |
---|---|
-f |
file exists and is regular |
-d |
directory exists |
-s |
file not empty |
-x |
executable |
-r |
readable |
-w |
writable |
! |
negate |
✅ Example:
if [[ -d "$HOME/.config" ]]; thenecho "Config dir exists"
fi
8. Functions Return Exit Codes, Not Values
Bash functions don’t return data — only exit statuses.
Use echo
to return data and capture it with command substitution.
sum() {echo $(( $1 + $2 ))
}result=$(sum 3 7)
echo "Result: $result"
If you need to signal success/failure, use return 0
or return 1
.
9. Handle Errors Intentionally
Use ||
and &&
to make logic explicit:
mkdir "$dir" || { echo "Cannot create $dir"; exit 1; }
Combine with set -e
to fail fast.
10. Use ShellCheck
Install ShellCheck (apt install shellcheck
, brew install shellcheck
).
Run it on your script:
shellcheck myscript.sh
It will detect most of the mistakes listed here — like pylint
for Bash.
11. Use printf
Instead of echo
echo
is inconsistent across systems.
printf
is predictable, portable, and safer:
printf "Hello, %s\n" "$name"
12. Beware of Subshells
Parentheses ()
create subshells.
Changes inside don’t affect parent shell:
(a=5)
echo "$a" # empty!
Use { ...; }
for grouping commands without subshells.
13. Prefer Long Options (if available)
Many built-ins and commands differ across shells.
Prefer --long-options
for clarity:
read -r -p "Enter name: " name
(-r
prevents backslash interpretation.)
14. Use trap
for Cleanup
Equivalent of Python’s try/finally
:
tmpfile=$(mktemp)
trap 'rm -f "$tmpfile"' EXIT# do work
15. Debugging Techniques
Add these for debugging:
set -x # print every command before execution
set +x # turn it off
Or run a script in debug mode:
bash -x script.sh
16. Avoid Useless Use of cat
You don’t need cat file | grep foo
; use:
grep foo file
This is called the UUOC (Useless Use of Cat) — a hallmark of beginners.
17. Prefer Explicit, Defensive Style
Python teaches clarity; carry that over.
Bad:
cp $1 $2
Good:
src=$1
dst=$2if [[ ! -f "$src" ]]; thenecho "Source not found: $src" >&2exit 1
ficp -- "$src" "$dst"
18. Avoid Backslashes for Line Continuation
Use &&
or \
sparingly. For multiline logic, use if
or { ... }
blocks instead.
19. Use Here Documents for Blocks
For multi-line text:
cat <<'EOF'
This will print
literally, without expansion
EOF
If you want variables to expand, omit the quotes on 'EOF'
.
20. Document Your Scripts
Bash becomes unreadable fast. Use comments generously:
# Update system and remove old logs
update_system() {sudo apt update && sudo apt upgrade -yrm -rf /var/log/*.old
}
Bonus: Safe Template for Every Script
Here’s a minimal safe skeleton:
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'main() {local arg1=${1:-}if [[ -z "$arg1" ]]; thenecho "Usage: $0 <argument>" >&2exit 1fiecho "Argument: $arg1"
}main "$@"
Summary Table
Category | Rule | Analogy (Python) |
---|---|---|
Quoting | Always quote variables | Avoid eval() |
Conditionals | Prefer [[ ]] |
Use if cleanly |
Arithmetic | Use (( )) |
Use int() not str() |
Strict Mode | set -euo pipefail |
Use exceptions |
Arrays | Use "${arr[@]}" |
Use lists |
ShellCheck | Static analysis | Like flake8 |
trap | Cleanup handler | finally: |
Functions | Echo results, return exit codes | Functions returning values |
Would you like me to produce a printable PDF version of this guide — formatted like a technical cheat sheet (two-column, monospace code, compact layout)? It’s perfect to keep beside your terminal.