Bash 命令速查表 - Shell 脚本编程常用语法大全

写脚本最容易踩的坑是空白文件名没加引号、变量为空时读了未定义值、以及忘记 set -euo pipefail。这张表把变量扩张、判断、循环、函数这些高频语法收纳,按"写出来就不容易翻车"的标准组织,照抄即可用。

系统与运维·共 91 条命令·最后更新 2026-09-10
bashshell脚本linux

典型使用场景

在服务器上写脚本、处理文本与日志、批量重命名与查找文件、管道组合命令,以及排查脚本权限、变量未导出、通配符未展开等常见问题。

变量 Variables 8

NAME="value"
定义变量(等号两边不能有空格)
echo $NAME
读取变量
echo ${NAME}
读取变量(推荐,避免歧义)
readonly NAME="value"
定义只读变量
unset NAME
删除变量
${VAR:-default}
变量为空时使用默认值
${VAR:=default}
变量为空时赋值并使用
${#VAR}
获取字符串长度

条件判断 Conditionals 7

if [ condition ]; then ... fi
if 语句
if [ -f file ]; then ... fi
判断文件是否存在
if [ $a -eq $b ]; then ... fi
数值比较(-eq -ne -gt -lt)
if [ "$str" = "value" ]; then ... fi
字符串比较(= !=)
if [[ $str =~ regex ]]; then ... fi
正则匹配(双括号)
[ -d dir ] && echo "exists"
短路写法
case $var in pattern1) ... ;; pattern2) ... ;; esac
case 语句

循环 Loops 6

for i in 1 2 3; do echo $i; done
for 循环遍历列表
for ((i=0; i<10; i++)); do ... done
C 风格 for 循环
while [ condition ]; do ... done
while 循环
until [ condition ]; do ... done
until 循环(条件为假时执行)
break / continue
跳出循环 / 跳过本次
select var in list; do ... done
交互式选择菜单

函数 Functions 7

function name() { ... }
定义函数
name() { ... }
定义函数(简写)
name arg1 arg2
调用函数
$1 $2 $@
位置参数 / 所有参数
$#
参数个数
return 0
返回值(0 表示成功)
local 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 ]
文件大小大于 0
[ file1 -nt file2 ]
file1 比 file2 新

高频补充命令(容量增强 · REQ-02) 36

${VAR:-default}
变量为空时取默认值,不改变原值
${VAR:=default}
变量为空时赋默认值并返回
${VAR:?error}
变量为空则打印错误并退出脚本
${VAR#prefix}
删除最短匹配的前缀
${VAR##prefix}
删除最长匹配的前缀
${VAR%suffix}
删除最短匹配的后缀
${VAR%%suffix}
删除最长匹配的后缀
${VAR:0:5}
截取子串(从第 0 个字符取 5 个)
${#VAR}
获取字符串长度
$(( a + b ))
算术展开,做加减乘除等运算
$(( i++ ))
算术自增
(( i > 5 )) && echo big
算术条件判断,成立才执行后续
[[ -z "$VAR" ]]
判断字符串是否为空
[[ "$a" == "b" ]]
字符串相等比较(推荐双方括号)
[[ "$a" =~ ^[0-9]+$ ]]
正则匹配,判断是否为纯数字
[ "$a" -gt 10 ]
数值大小比较(单方括号)
for i in {1..10}; do echo $i; done
序列循环,遍历 1 到 10
for f in *.txt; do echo $f; done
遍历当前目录所有 txt 文件
while read -r line; do echo $line; done < file
逐行读取文件内容
while getopts ":a:b:" opt; do :; done
解析命令行短选项参数
case "$x" in a) echo a;; b) echo b;; esac
多分支条件匹配
select menu in opt1 opt2; do break; done
生成交互式数字选择菜单
command > file 2>&1
标准输出与错误都重定向到文件
cmd1 && cmd2
仅当前一条成功才执行后一条
cmd1 || cmd2
仅当前一条失败才执行后一条
cmd1 | cmd2
管道:前一条输出作为后一条输入
tee -a log.txt
输出既写屏幕又追加到文件
set -e
任一条命令失败立即退出脚本
set -u
引用未定义变量时报错退出
set -o pipefail
管道中任意命令失败即判定整体失败
trap cleanup EXIT
脚本退出时执行清理函数
read -p "name: " name
交互式读取用户输入到变量
printf "%-10s %s\n" "$a" "$b"
按格式对齐输出(左对齐 10 宽)
xargs -I{} cp {} dest/
将输入逐项代入占位符执行命令
command -v <name>
判断命令是否存在(比 which 更可移植)
source ./env.sh
在当前 shell 中执行脚本(点号 . 等价)

参数展开与调试(REQ-02 补充) 12

${var:-default}
变量未定义或为空时使用默认值
${var:=default}
为空时赋默认值并回写变量
${var:?message}
为空时报错退出并输出提示
${var#pattern}
从开头最短匹配并删除
${var%pattern}
从结尾最短匹配并删除
${var/pattern/replace}
替换首个匹配的内容
${var^^}
将变量内容转为大写
${#var}
取变量内容的字符长度
set -x
开启执行追踪,打印每条展开后的命令
bash -n script.sh
只做语法检查而不执行脚本
shopt -s nullglob
通配符无匹配时展开为空而非原样
getopts "a:b" opt
解析脚本短选项参数

参数矩阵

参数作用示例
-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/

易错点与避坑指南

现象脚本报 Permission denied 无法执行。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

现象rm 误删了不该删的文件。

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

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

排障路径

  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 看最新样例。

命令示例

给变量设默认值

NAME=${NAME:-lzh} echo "$NAME"

${var:-default} 在变量未设或为空时取 default;改用 ${var-default} 只在完全未设时才取。

输出

lzh   # NAME 未设时输出默认值;已设则输出原值

判断文件是否存在

if [[ -f /etc/nginx.conf ]]; then echo exists else echo missing fi

用 [[ ]] 而非 [ ],支持 && 与 || 且不会错误分词;变量务必用双引号包裹,避免空值时语法报错。

输出

exists

获取脚本自身所在目录

DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" echo "$DIR"

用 BASH_SOURCE[0] 而非 $0,这样即使脚本被 source 引入,拿到的也是其真实所在目录。

输出

/home/deploy/scripts

常见坑与注意事项

  • 判断与算术一律优先用 [[ ]] 和 (( )),避免 [ ] 在空变量或带通配符的字符串下报语法错误。
  • 双引号包变量是铁律:for i in $LIST、rm $f 这类写法不引号,遇空格或通配符会错拆词、误删文件。
  • set -e 表示出错即停:脚本中某行失败会立即退出而非继续,重要脚本建议开启,防止失败后还在往下跑造成连锁问题。
  • 函数内的变量默认是全局作用域,忘了写 local 会污染全局变量,同名变量极易踩到难以排查的坑。
  • rm -rf 与 > 重定向都会真正删除或覆写文件,执行前先 echo 预览或做防护,避免误操作线上数据。

提示

  • 变量赋值时等号两边不能有空格,否则会被解释为命令。
  • 使用双引号包裹变量("$VAR")避免空格和特殊字符问题。
  • [ ] 是 test 命令的语法糖,[[ ]] 是 Bash 扩展,支持更多功能如正则匹配。

常见问题

脚本开头常写的 set -euo pipefail 到底各自干什么?

set -e 遇错即退,但命令出现在 if/while/&&/|| 等条件位置或管道非末段时不会触发退出;-u 让引用未定义变量直接报错;-o pipefail 让管道的退出码取各段中最右的非零值,而不是只看末段。组合起来能尽早暴露错误,是健壮脚本的标配。

单引号和双引号包变量,为什么一个能展开一个不能?

双引号内 $变量、$(命令) 和反引号都会正常展开,单引号把内容当字面量完全不做处理,适合包路径、正则或确实无需展开的文本。含空格的路径务必用双引号包住变量,否则会被分词拆开。

$@ 和 $* 到底有什么区别?

不加引号时两者等价,都会把参数按空格分词;关键差别在加了引号之后:@ 形式把每个参数当作独立的一个词保留,* 形式把所有参数合并成一个字符串。遍历脚本参数时优先用加引号的 @ 形式。

想逐行读取一个文件去处理,怎么写才不含糊?

用 while IFS= read -r line; do ...; done < file,IFS= 防止裁掉行首尾空白,-r 防止把反斜杠当转义。别用 for line in $(cat file),那会按空白把内容拆成词而丢失每行的结构。

脚本里怎么判断上一条命令成功与否,又怎样主动让它失败?

$? 保存紧邻上一条命令的退出码,0 表示成功、非 0 表示失败,先把它存进变量再判断最稳妥。主动退出非 0 用 exit 1,返回 0 表示成功;配合 set -e,脚本遇到未捕获的失败会自动退出。

官方参考来源

下方为命令对应的官方权威文档,供你核对最新用法与深入查阅。

由 巧匠 维护

公开更新于 2026年9月10日,内容持续校对官方文档。

联系我们

命令或描述有误?提交反馈、商务合作或产品建议都可发送邮件给我们。

联系我们