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.

SysOps·55 commands·Last updated 2026-09-10
bashshellScriptinglinux

Typical Use Case

Write scripts, process text and logs, batch rename and find files, compose pipelines on servers, and troubleshoot script permission, unexported variables, and unexpanded globs.

Variables 8

NAME="value"
Define variable (no spaces around =)
echo $NAME
Read variable
echo ${NAME}
Read variable (recommended, avoids ambiguity)
readonly NAME="value"
Define readonly variable
unset NAME
Delete variable
${VAR:-default}
Use default value if variable is empty
${VAR:=default}
Assign and use default if variable is empty
${#VAR}
Get string length

Conditionals 7

if [ condition ]; then ... fi
if statement
if [ -f file ]; then ... fi
Check if file exists
if [ $a -eq $b ]; then ... fi
Numeric comparison (-eq -ne -gt -lt)
if [ "$str" = "value" ]; then ... fi
String comparison (= !=)
if [[ $str =~ regex ]]; then ... fi
Regex match (double brackets)
[ -d dir ] && echo "exists"
Short-circuit evaluation
case $var in pattern1) ... ;; pattern2) ... ;; esac
case statement

Loops 6

for i in 1 2 3; do echo $i; done
for loop over a list
for ((i=0; i<10; i++)); do ... done
C-style for loop
while [ condition ]; do ... done
while loop
until [ condition ]; do ... done
until loop (executes while condition is false)
break / continue
Break out of loop / skip iteration
select var in list; do ... done
Interactive selection menu

Functions 7

function name() { ... }
Define a function
name() { ... }
Define function (shorthand)
name arg1 arg2
Call a function
$1 $2 $@
Positional parameters / all parameters
$#
Number of parameters
return 0
Return value (0 means success)
local var="value"
Local variable

String Operations 7

${VAR:offset:length}
Substring extraction
${VAR#pattern}
Remove shortest matching prefix
${VAR##pattern}
Remove longest matching prefix
${VAR%pattern}
Remove shortest matching suffix
${VAR%%pattern}
Remove longest matching suffix
${VAR/pattern/replacement}
Replace first match
${VAR//pattern/replacement}
Replace all matches

File Tests 8

[ -f file ]
File exists and is a regular file
[ -d dir ]
Directory exists
[ -e path ]
Path exists
[ -r file ]
File is readable
[ -w file ]
File is writable
[ -x file ]
File is executable
[ -s file ]
File size is greater than 0
[ file1 -nt file2 ]
file1 is newer than file2

Parameter Expansion & Debugging (REQ-02 add-on) 12

${var:-default}
Use default when var is unset or empty
${var:=default}
Assign default and write back when empty
${var:?message}
Exit with an error message when empty
${var#pattern}
Remove shortest match from the beginning
${var%pattern}
Remove shortest match from the end
${var/pattern/replace}
Replace the first match
${var^^}
Convert variable content to uppercase
${#var}
Get the character length of a variable
set -x
Enable execution trace of expanded commands
bash -n script.sh
Syntax-check a script without running it
shopt -s nullglob
Expand unmatched globs to empty instead of literal
getopts "a:b" opt
Parse short options in a script

Parameter matrix

参数EffectExample
-x执行时打印每条命令,便于调试脚本bash -x script.sh
-e命令失败时立即退出脚本set -e
-u使用未定义变量时报错set -u
-o pipefail管道任一环节失败即视为失败set -eo pipefail
2>重定向标准错误cmd 2>/dev/null
|管道,前一命令输出作为后一输入cat log | grep error | wc -l
$()命令替换,捕获输出now=$(date +%F)
&& / ||前令成功/失败才执行后令make && make install
-name / -typefind 按名/按类型查找find . -name "*.log" -mtime +7
-i忽略大小写(grep 等)grep -ri error log/

Common pitfalls

Symptom脚本报 Permission denied 无法执行。

Cause文件没有可执行位,或脚本首行 shebang 指向不存在的解释器。

Fixchmod +x script.sh;确认首行 #!/usr/bin/env bash 且 bash 路径存在。

Symptom变量在子 shell/脚本中为空。

Cause未用 export 导出,或作用域仅限当前 shell。

Fix用 export VAR=val 让子进程可见;在脚本内统一用 local/全局变量声明。

Symptomfor f in * 通配符没展开,被当成字面量。

Cause目录为空时 nullglob 未开启,* 保持原样传给命令。

Fix开启 shopt -s nullglob;或用 find ... -print0 | xargs -0 处理空目录情况。

Symptom重定向或管道把文件清空了。

Cause命令如 cat file > file 在读取前先截断目标。

Fix重定向到不同文件或临时文件再覆盖;小心 > 与 >> 的方向。

Symptom空格/特殊字符把文件名拆成多个参数。

Cause未对变量加双引号,IFS 按空格/制表符切割。

Fix始终用 "$var" 包裹变量;处理文件名用 while IFS= read -r line 与 find -print0。

Symptomrm 误删了不该删的文件。

Cause通配符匹配过宽,或路径变量为空。

Fixrm 前先 echo 看匹配结果;危险操作加 -i 确认;避免在变量为空时 rm -rf "$dir"/*。

Troubleshooting

  1. 1调试脚本每一步

    bash -x script.sh

    打印实际执行的命令与变量展开,定位逻辑错误。

  2. 2确认脚本语法无误

    bash -n script.sh

    只做语法检查不执行,适合上线前校验。

  3. 3定位最近修改的大文件

    find /var -type f -size +100M -mtime -1

    排查磁盘突增时快速定位可疑文件。

  4. 4统计日志中错误出现次数

    grep -ci error /var/log/app.log

    快速评估错误规模,结合 tail 看最新样例。

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 Sep 10, 2026, continuously proofread against official docs.

Contact Us

Wrong command or description? Send us corrections, business inquiries or product feedback by email.

Contact Us