Bash Cheatsheet - Shell Scripting Command Reference
Most Bash scripts only need a few patterns done right: quoting and ${VAR:-default} guards, $? and test conditions, for/while loops, and functions instead of copy-paste. This table is the subset you actually reach for while writing or fixing scripts — pair it with `set -euo pipefail` and the script stops being fragile.
Variables 8
NAME="value"echo $NAMEecho ${NAME}readonly NAME="value"unset NAME${VAR:-default}${VAR:=default}${#VAR}Conditionals 7
if [ condition ]; then ... fiif [ -f file ]; then ... fiif [ $a -eq $b ]; then ... fiif [ "$str" = "value" ]; then ... fiif [[ $str =~ regex ]]; then ... fi[ -d dir ] && echo "exists"case $var in pattern1) ... ;; pattern2) ... ;; esacLoops 6
for i in 1 2 3; do echo $i; donefor ((i=0; i<10; i++)); do ... donewhile [ condition ]; do ... doneuntil [ condition ]; do ... donebreak / continueselect var in list; do ... doneFunctions 7
function name() { ... }name() { ... }name arg1 arg2$1 $2 $@$#return 0local var="value"String Operations 7
${VAR:offset:length}${VAR#pattern}${VAR##pattern}${VAR%pattern}${VAR%%pattern}${VAR/pattern/replacement}${VAR//pattern/replacement}File Tests 8
[ -f file ][ -d dir ][ -e path ][ -r file ][ -w file ][ -x file ][ -s file ][ file1 -nt file2 ]Typical Use Case
Nine out of ten script failures come from details, not syntax. The most typical case is writing for i in $LIST without quotes so spaces in paths split into multiple words; another frequent trap is using [ instead of [[, where an empty variable or a string with wildcards raises a syntax error. This table explains these pitfalls with runnable examples: defaulting variables with ${var:-default}, safe file tests with [[ -f ]], and failing fast with set -e. After reading, you can audit your production scripts against it.
Command Examples
Default a possibly-unset variable
NAME=${NAME:-lzh}
echo "$NAME"${var:-default} 在变量未设或为空时取 default;改用 ${var-default} 只在完全未设时才取。
Output
lzh # NAME 未设时输出默认值;已设则输出原值
Test whether a file exists
if [[ -f /etc/nginx.conf ]]; then
echo exists
else
echo missing
fi用 [[ ]] 而非 [ ],支持 && 与 || 且不会错误分词;变量务必用双引号包裹,避免空值时语法报错。
Output
exists
Resolve the directory of the running script
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "$DIR"用 BASH_SOURCE[0] 而非 $0,这样即使脚本被 source 引入,拿到的也是其真实所在目录。
Output
/home/deploy/scripts
Common Pitfalls
- Prefer [[ ]] and (( )) for tests and arithmetic; [ ] trips on empty variables or strings containing wildcards.
- Quoting variables is a hard rule: for i in $LIST or rm $f without quotes split words or delete the wrong files when spaces or globs are involved.
- set -e means fail fast: a failing line exits instead of continuing. Enable it in important scripts to avoid cascading failures.
- Variables in functions are global by default; forgetting local pollutes globals and setups with the same name are easy to hit.
- Both rm -rf and > redirection really delete or overwrite; echo the command as a preview or guard before running against production data.
Tips
- No spaces around = in variable assignment, or it will be interpreted as a command.
- Always quote variables ("$VAR") to avoid word splitting and special character issues.
- [ ] is syntactic sugar for the test command; [[ ]] is a Bash extension with more features like regex matching.
FAQ
What do set -euo pipefail do respectively at the top of a Bash script?
set -e exits on an error, but a failing command does not trigger the exit when it appears in a condition such as if/while/&&/|| or in the middle of a pipeline; -u makes referencing an undefined variable an error; -o pipefail makes a pipeline return the rightmost non-zero exit code among its commands rather than only the last one. Combined they surface errors early and are the standard for robust scripts.
Why does a variable expand inside double quotes but not single quotes in Bash?
Inside double quotes, $variables, $(commands), and backticks are expanded normally, whereas single quotes treat everything literally with no expansion, which suits paths, regexes, or text that must stay untouched. Always wrap a variable holding a path you want to keep intact in double quotes, or word splitting will break it apart.
What is the difference between $@ and $* in Bash?
Without quoting both are equivalent and split the arguments on whitespace. The decisive difference appears when quoted: the @ form preserves each argument as a separate word, whereas the * form joins all arguments into one string. Prefer the quoted at-sign form when iterating over positional parameters.
How do I read a file line by line in Bash robustly?
Use while IFS= read -r line; do ...; done < file. IFS= prevents stripping leading and trailing whitespace, and -r keeps backslashes literal. Do not use for line in $(cat file), which splits the file into words on whitespace and loses line structure.
How do I check whether the previous command succeeded, and how do I make my script fail on purpose in Bash?
$? holds the exit status of the immediately preceding command, where 0 means success and non-zero means failure, so copy it into a variable before checking. Use exit 1 to exit with a non-zero status deliberately, while exit 0 signals success. Combined with set -e, the script automatically aborts on any uncaught failure.
Official References
Each command links to its official documentation below, so you can verify the latest usage and read deeper.
Maintained by LaoHand
Publicly updated on Jul 21, 2026, continuously proofread against official docs.
Contact Us
Wrong command or description? Send us corrections, business inquiries or product feedback by email.
Contact Us