一、Bash 替换机制的核心分类
Bash 替换主要分为 6 类,覆盖变量、命令、算术、文件名、参数、进程等场景,每类都有明确的使用场景和语法:
| 替换类型 | 语法特征 | 核心作用 |
|---|---|---|
| 变量替换 | $var/${var} |
用变量的实际值替换变量名,最基础也最常用 |
| 命令替换 | command/$(command) |
执行括号 / 反引号内的命令,用输出结果替换原表达式 |
| 算术替换 | $((表达式)) |
计算整数算术表达式,用计算结果替换 |
| 文件名替换 | */?/[] |
匹配符合通配符规则的文件 / 目录名,替换成具体名称列表 |
| 参数替换 | ${var:-默认值}等 |
对变量进行条件处理(如无值时赋默认值、空值时报错),返回处理后的结果 |
| 进程替换 | <(command)/>(command) |
将命令输出作为临时文件 / 管道,替换成文件描述符(进阶场景) |
二、核心替换类型详解(附示例)
1. 变量替换(最基础)
语法 :$变量名 或 ${变量名}(推荐用花括号,避免歧义)作用 :把变量名替换成变量存储的实际值。示例:
bash
运行
# 定义变量
name="Bash"
# 变量替换:$name 会被替换成 "Bash"
echo "Hello $name" # 执行后输出:Hello Bash
# 花括号避免歧义(不加会识别成 $nameWorld,变量不存在则为空)
echo "Hello ${name}World" # 输出:Hello BashWorld
2. 命令替换(高频使用)
语法 :$(命令)(推荐)或 命令(旧语法,嵌套易出错)作用 :先执行命令,再用命令的输出结果替换原表达式。示例:
bash
运行
# 获取当前日期,替换后 echo 输出日期
echo "当前时间:$(date +%Y-%m-%d)" # 输出:当前时间:2025-12-22
# 嵌套示例($(()) 更友好)
echo "当前目录文件数:$(ls | wc -l)" # 输出:当前目录文件数:xxx(具体数字)
3. 算术替换(整数计算)
语法 :$((算术表达式))支持运算 :+ - * / %(加减乘除取余)、++ --(自增自减)、== !=(比较)等。示例:
bash
运行
a=10
b=3
# 计算 10+3,替换后输出 13
echo "a+b = $((a + b))" # 输出:a+b = 13
# 计算 10%3,替换后输出 1
echo "a%b = $((a % b))" # 输出:a%b = 1
# 自增运算
echo "a++ = $((a++))" # 输出:a++ = 10(先取值后自增)
echo "++a = $((++a))" # 输出:++a = 12(先自增后取值)
4. 文件名替换(通配符匹配)
语法 :*(匹配任意字符)、?(匹配单个字符)、[](匹配指定范围)作用 :Bash 会先匹配符合规则的文件,再替换成文件名列表。示例:
bash
运行
# 匹配当前目录所有 .sh 文件,替换成具体文件名后执行 ls
ls *.sh # 输出:test.sh demo.sh(当前目录的 sh 文件)
# 匹配以 a 或 b 开头的文件
ls [ab]* # 输出:a.txt b.log(符合的文件)
# 匹配文件名是 3 个字符的文件(? 匹配单个)
ls ???.txt # 输出:abc.txt(仅匹配3字符+txt的文件)
5. 参数替换(变量条件处理)
语法 & 场景:这是变量替换的进阶,解决 "变量为空 / 不存在" 的场景,常用语法如下:
| 语法 | 作用(变量 var 不存在 / 为空时) | 变量有值时 |
|---|---|---|
${var:-默认值} |
返回默认值 | 返回变量值 |
${var:=默认值} |
返回默认值,且给 var 赋值默认值 | 返回变量值 |
${var:?报错信息} |
输出报错信息并终止脚本 | 返回变量值 |
${var:+替代值} |
返回空 | 返回替代值 |
示例:
bash
运行
# 场景1:变量为空时用默认值
unset test_var # 清空变量
echo "test_var: ${test_var:-默认值}" # 输出:test_var: 默认值
# 场景2:变量为空时赋值+返回默认值
echo "test_var: ${test_var:=新值}" # 输出:test_var: 新值
echo "test_var 现在的值:$test_var" # 输出:test_var 现在的值:新值
# 场景3:变量为空时报错
# echo "test_var: ${empty_var:?变量为空!}" # 执行后报错:-bash: empty_var: 变量为空!
6. 进程替换(进阶,管道替代)
语法 :<(命令)(把命令输出当成 "只读文件")、>(命令)(把输入当成 "只写文件")作用 :适用于需要 "文件作为参数" 但只有命令输出的场景(比如对比两个命令的输出)。示例:
bash
运行
# 对比 ls 和 ls -a 的输出差异(diff 需要文件参数,用进程替换模拟文件)
diff <(ls) <(ls -a)
三、关键注意事项(避坑重点)
-
替换顺序 :Bash 执行命令前会按「括号 / 引号 → 通配符 → 变量 / 命令 / 算术替换 → 执行命令」的顺序处理,比如引号会阻止替换:
bash
运行
# 单引号内所有替换都失效,直接输出 $name echo 'Hello $name' # 输出:Hello $name # 双引号内仅变量/命令替换生效,通配符/算术替换失效 echo "当前文件数:$(ls | wc -l) *.sh" # 输出:当前文件数:5 *.sh(*.sh 不匹配) -
空格与引号 :替换结果含空格时,需用双引号包裹,避免被拆分成多个参数:
bash
运行
file_name="my file.txt" # 不加引号:ls 会识别成 ls my file.txt(找 my 和 file.txt 两个文件) ls "$file_name" # 加引号:正确识别成 ls "my file.txt" -
嵌套替换 :命令替换支持嵌套,优先用
$(())而非反引号(反引号嵌套需转义,易出错):bash
运行
# 推荐:嵌套清晰 echo "嵌套结果:$(echo $((10 + 5)))" # 输出:嵌套结果:15 # 不推荐:反引号嵌套需转义 # echo "嵌套结果:`echo \`expr 10 + 5\``"
总结
- Bash 替换机制是执行命令前的 "预处理",核心是把特殊表达式替换成实际值 / 结果,再执行最终命令;
- 高频替换类型:变量替换 (
${var})、命令替换 ($(command))、算术替换 ($((expr)))是新手必掌握的核心; - 避坑关键:单引号阻止所有替换、双引号保留变量 / 命令替换、替换含空格时用双引号包裹。