Shell 语法、变量与字符串处理
更新时间:2026-08-25。本文覆盖 Shell 编程主题的第①族:语法、变量、数组、引号、字符串处理,约 18 个常用命令/语法点。
一、变量
1.1 声明与使用
bash
name="world" # 赋值,等号两侧不能有空格
echo "$name" # 使用:加 $,最好加双引号防空格分词
readonly pi=3.14 # 只读变量
unset name # 删除变量1.2 特殊变量
| 变量 | 含义 |
|---|---|
$0 | 脚本名 |
$1 $2 … | 位置参数 |
$# | 参数个数 |
$@ | 全部参数(每个独立) |
$* | 全部参数(整体一个字符串) |
$? | 上一条命令退出码(0 成功,非 0 失败) |
$$ | 当前进程 PID |
$! | 最后一个后台进程 PID |
$- | 当前 shell 选项 |
$_ | 上一条命令的最后一个参数 |
1.3 命令替换与算术
bash
files=$(ls) # 命令替换,等价于 `ls`
count=$((1 + 2 * 3)) # 算术运算($((...)))二、数组
bash
# 索引数组
arr=(a b c)
arr[3]=d
echo "${arr[0]}" # a
echo "${#arr[@]}" # 元素个数
echo "${arr[@]}" # 全部元素
# 关联数组(Bash 4+)
declare -A scores
scores[alice]=90
echo "${scores[alice]}"三、引号的三种语义(必考)
| 引号 | 作用 |
|---|---|
'...' 单引号 | 原样,不解析任何变量/特殊字符 |
"..." 双引号 | 解析 $变量、\ 转义、$(),但不做分词与通配符展开 |
`...` / $(...) | 命令替换 |
bash
v="hello"
echo '$v' # 输出 $v
echo "$v" # 输出 hello
echo `echo $v` # 输出 hello(命令替换)经验法则:能用双引号就用双引号("$var"),防止变量含空格被拆词导致 bug。
四、字符串处理(Bash 内置)
bash
s="hello world"
# 取长度
echo "${#s}" # 11
# 切片
echo "${s:0:5}" # hello(从第 0 个取 5 个)
echo "${s:6}" # world(从第 6 个到末尾)
# 删除前缀/后缀
echo "${s#hello }" # world(删最短前缀)
echo "${s##* }" # world(删最长前缀,贪婪)
echo "${s% world}" # hello(删最短后缀)
echo "${s%%.*}" # (删最长后缀)
# 替换
echo "${s/world/earth}" # hello earth(替换第一个)
echo "${s//o/0}" # hell0 w0rld(替换所有)
# 大小写
echo "${s^^}" # HELLO WORLD(大写)
echo "${s,,}" # hello world(小写)
# 默认值
echo "${s:-fallback}" # 未设/空时用默认值
echo "${s:=fallback}" # 未设/空时赋默认值并输出
echo "${s:+alt}" # 已设非空时输出 alt五、常用文本相关内置命令
| 命令 | 作用 | 示例 |
|---|---|---|
echo | 输出(-e 解析转义,-n 不换行) | echo -e "a\tb" |
printf | 格式化输出(比 echo 更可控) | printf "%s-%d\n" name 42 |
read | 从标准输入读一行 | read -p "输入: " val |
test / [ | 测试表达式 | [ -f file ]、[ "$a" = "$b" ] |
expr | 表达式求值(旧式) | expr 1 + 1(现代用 $((...))) |
六、错误处理模板(学完即用)
bash
#!/bin/bash
set -euo pipefail # 任何错误即退出;未定义变量报错;管道错误可见
set -x # 调试:打印每条命令(上线前注释掉)
log() { printf '[%s] %s\n' "$(date '+%F %T')" "$*"; }
if [ $# -lt 1 ]; then
echo "用法: $0 <目标目录>" >&2 # 错误输出到 stderr
exit 1
fi
target=$1
log "开始处理 $target"
# ... 业务七、与主线衔接
- 字符串切片/替换是日志字段清洗的基础,配合 文本处理命令 的
sed/awk。 set -euo pipefail保证脚本在管道失败时不静默吞错——这对自动化部署脚本的稳健性至关重要。- 变量与
$?的运用,是一切"根据命令结果决定后续动作"的脚本逻辑起点。
一句话总结
Shell 变量与字符串 = 三引号语义(单原样/双解析/反引号替换)+ $() 与 $((...)) + 数组 + ${var:offset:len} 与 ${var//旧/新};set -euo pipefail 是每个可靠脚本的起手式。