如何在 Shell 脚本中正确读取包含空格的配置文件变量?

文章导读
在 Shell 脚本中读取含空格的配置变量,最稳妥的方式是让配置文件本身符合 Shell 语法并使用 source 命令加载,或者使用 while IFS='=' read -r 逐行解析。关键风险在于变量引用时必须加双引号,否则空格会导致参数分裂。
📋 目录
  1. A 命令速用版
  2. B 为什么会这样
  3. C 分步处理
  4. D 怎么验证是否生效
  5. E 常见坑
  6. F 常见问题
A A

在 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"。

如何在 Shell 脚本中正确读取包含空格的配置文件变量?

步骤 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 错误。

如何在 Shell 脚本中正确读取包含空格的配置文件变量?

常见坑

  • 变量引用未加双引号:导致含空格的值被拆分成多个参数。
  • 使用 eval 加载不可信配置:可能导致任意命令执行风险。
  • 配置文件含 Windows 换行符:导致变量值末尾包含\r,影响路径或密码验证。
  • key=value 等号两侧有空格:解析时需 trim 空白,否则值前会带空格。

常见问题

配置文件里的值必须加引号吗?

若使用 source 加载且值含空格,必须加双引号。若使用 read 解析,值不加引号也可读取,但引用变量时仍需加双引号。

可以直接用 cat 和 grep 读取变量吗?

不推荐。grep 只能提取文本,无法直接变成 Shell 变量。需配合 export 和 eval 使用,但 eval 有安全风险,建议用 while read 循环。

如何避免配置中的注释干扰读取?

在 read 循环中加入判断,跳过以#开头的行。例如:[[ $key =~ ^# ]] && continue。