在 Shell 脚本中读取含空格的配置变量,最稳妥的方式是让配置文件本身符合 Shell 语法并使用 source 命令加载,或者使用 while IFS='=' read -r 逐行解析。关键风险在于变量引用时必须加双引号,否则空格会导致参数分裂。
先说结论:优先采用 source 加载符合 Shell 语法的配置文件,若配置文件格式不可控则使用 read 命令解析,使用时必须给变量加双引号。
- 适合:bash/sh 脚本读取 key=value 格式配置,值中包含空格或特殊字符的场景
- 先看:配置文件是否包含空格、是否含有特殊符号、是否包含注释
- 建议:变量引用处统一加双引号,避免使用 eval 处理不可信配置
命令速用版
# 方法 1:配置文件符合 Shell 语法(推荐)
source ./config.sh
echo "$MY_VAR"
# 方法 2:配置文件仅为 key=value(需解析)
while IFS='=' read -r key value; do
export "$key"="$value"
done < ./config.conf
echo "$MY_VAR"为什么会这样
Shell 默认将空格视为参数分隔符。读取变量时如果不加双引号,Shell 会根据 IFS(内部字段分隔符)把含空格的值拆分成多个参数。配置文件解析时若不使用 read -r 或不当使用 eval,会导致空格截断或命令注入风险。
分步处理
步骤 1:确认配置文件格式
检查配置文件是纯 key=value 还是可执行的 Shell 脚本。若是前者,值两侧建议加双引号,如 VAR="hello world"。
步骤 2:选择加载方式
若文件可信且符合 Shell 语法,使用 source ./config.sh。若文件仅文本格式,使用 while read 循环逐行赋值,避免直接 eval。
步骤 3:脚本引用变量
在脚本中使用变量时,始终写作 "$VAR" 而不是 $VAR。双引号能保留空格和特殊字符原样。
步骤 4:处理 Windows 换行符
若配置文件在 Windows 编辑过,可能含\r 字符。使用 sed 's/\r$//' config.conf > config_unix.conf 预处理。
怎么验证是否生效
在脚本中添加 echo "DEBUG: [$VAR]" 命令。若输出为 DEBUG: [hello world] 则空格保留完整。若输出为 DEBUG: [hello world] 且后续命令报错参数过多,说明空格导致了分裂。检查日志中是否有 command not found 或 extra operand 错误。
常见坑
- 变量引用未加双引号:导致含空格的值被拆分成多个参数。
- 使用 eval 加载不可信配置:可能导致任意命令执行风险。
- 配置文件含 Windows 换行符:导致变量值末尾包含\r,影响路径或密码验证。
- key=value 等号两侧有空格:解析时需 trim 空白,否则值前会带空格。
常见问题
配置文件里的值必须加引号吗?
若使用 source 加载且值含空格,必须加双引号。若使用 read 解析,值不加引号也可读取,但引用变量时仍需加双引号。
可以直接用 cat 和 grep 读取变量吗?
不推荐。grep 只能提取文本,无法直接变成 Shell 变量。需配合 export 和 eval 使用,但 eval 有安全风险,建议用 while read 循环。
如何避免配置中的注释干扰读取?
在 read 循环中加入判断,跳过以#开头的行。例如:[[ $key =~ ^# ]] && continue。