替换运算符
Shell 变量替换运算符:处理未定义或空值的实用技巧
在 Shell 脚本中,变量未定义或为空时直接使用可能导致逻辑错误或脚本中断。替换运算符提供了灵活的方式处理这类情况,确保脚本更健壮。以下是四种常用替换运算符的详细解析和示例。
${varname:-word}:默认值替换
作用
- 若变量
varname已定义且非空,返回变量值; - 若变量 未定义或为空,返回
word(不改变变量本身的值)。
适用场景
为变量设置默认值,避免因变量未定义导致的错误(如命令参数缺失)。
示例
# 变量未定义
echo "Hello, ${name:-Guest}!" # 输出:Hello, Guest!
# 变量为空
name=""
echo "Hello, ${name:-Guest}!" # 输出:Hello, Guest!
# 变量有值
name="Alice"
echo "Hello, ${name:-Guest}!" # 输出:Hello, Alice!
# 命令中使用(若dir未定义,默认使用当前目录)
dir=""
ls ${dir:-.} # 等价于 ls .(列出当前目录内容)
${varname:=word}:赋值并返回默认值
作用
- 若变量
varname已定义且非空,返回变量值; - 若变量 未定义或为空,将变量值设为
word,并返回word(会修改变量本身)。
适用场景
需要为未定义的变量自动赋值,确保后续逻辑中变量有有效值。
示例
# 变量未定义
echo "初始值:${count:=0}" # 输出:初始值:0(count被赋值为0)
echo "赋值后:$count" # 输出:赋值后:0
# 变量为空
count=""
echo "重置值:${count:=5}" # 输出:重置值:5(count被赋值为5)
echo "重置后:$count" # 输出:重置后:5
# 变量有值
count=10
echo "原值:${count:=20}" # 输出:原值:10(count保持不变)
注意
- 在 Shell 函数中,
${var:=word}会修改全局变量,若需局部变量需结合local声明。
${varname:?message}:未定义时报错退出
作用
- 若变量
varname已定义且非空,返回变量值; - 若变量 未定义或为空,输出错误信息
varname: message,并退出当前脚本或命令(非交互式 Shell 中)。
适用场景
验证必填变量是否存在,若缺失则终止脚本并提示原因(如配置文件路径、用户名等)。
示例
# 脚本中验证必填变量
#!/bin/bash
# 文件名:deploy.sh
# 若未传入参数1($1),则报错退出
echo "部署路径:${1:?请指定部署目录}"
# 执行脚本(未传参数)
# sh deploy.sh
# 输出:deploy.sh: line 4: 1: 请指定部署目录(脚本退出)
# 执行脚本(传入参数)
# sh deploy.sh /opt/app
# 输出:部署路径:/opt/app(脚本继续执行)
${varname:+word}:存在时返回替代值
作用
- 若变量
varname已定义且非空,返回word; - 若变量 未定义或为空,返回空值(不改变变量本身)。
适用场景
根据变量是否存在,返回特定的替代值(如条件性添加命令参数)。
示例
# 变量有值
debug=1
echo "运行模式:${debug:+调试模式}" # 输出:运行模式:调试模式
# 变量未定义
unset debug
echo "运行模式:${debug:+调试模式}" # 输出:运行模式:(空值)
# 命令中使用(若enable_log存在,添加日志参数)
enable_log=1
command ${enable_log:+--log /var/log/run.log}
# 等价于 command --log /var/log/run.log
unset enable_log
command ${enable_log:+--log /var/log/run.log}
# 等价于 command(无日志参数)
替换运算符对比表
| 运算符 | 变量存在且非空 | 变量未定义或空 | 核心用途 |
|---|---|---|---|
${var:-word} |
返回 var 值 |
返回 word |
提供默认值(不修改变量) |
${var:=word} |
返回 var 值 |
设 var=word 并返回 word |
自动赋值默认值(修改变量) |
${var:?msg} |
返回 var 值 |
报错并退出 | 验证必填变量 |
${var:+word} |
返回 word |
返回空 | 条件性返回替代值 |
实际应用场景
脚本参数处理:
# 为脚本参数设置默认值 port=${1:-8080} # 若未传参数,默认端口8080配置文件加载:
# 若配置文件未指定,使用默认路径并赋值 config_file=${CONFIG_FILE:=/etc/app/config.ini}必填参数校验:
# 确保数据库密码已设置 ${DB_PASSWORD:?环境变量DB_PASSWORD未配置}条件性命令参数:
# 若开启verbose模式,添加-v参数 verbose=1 cmd ${verbose:+ -v} # 等价于 cmd -v