Shell脚本将环境变量写入config.json时文件为空的问题
解决Shell脚本修改config.json后文件为空的问题
问题原因
你的脚本中出现文件为空的核心问题是Shell重定向的执行顺序:
当你执行jq ... src/assets/config.json > src/assets/config.json时,Shell会先执行右侧的>重定向操作,直接清空目标文件src/assets/config.json,之后才会让jq去读取这个已经被清空的文件,最终jq输出空内容写入文件。循环每一次都会重复这个过程,导致最终文件完全为空。
解决方案
方案1:使用临时文件避免直接覆盖
通过临时文件作为中间载体,先读取原文件处理后写入临时文件,再替换原文件,避免读取和写入同时操作同一个文件:
# 创建临时文件 TEMP=$(mktemp) # 复制原配置到临时文件 cp src/assets/config.json "$TEMP" env | while IFS= read -r line; do value=${line#*=} name=${line%%=*} # 处理临时文件并写入临时副本,替换临时文件 jq --arg name "$name" --arg value "$value" '.[$name] = $value' "$TEMP" > "$TEMP.tmp" && mv "$TEMP.tmp" "$TEMP" done # 将处理后的临时文件替换回原配置 mv "$TEMP" src/assets/config.json # 查看最终配置 jq . src/assets/config.json
方案2:一次性合并所有环境变量(更高效)
避免循环多次调用jq,直接将所有环境变量转换为JSON对象,一次性合并到原配置中,效率更高:
# 将环境变量转换为JSON对象,再与原配置合并 env | jq -n 'reduce inputs as $line ({}; ($line | split("="; limit=2)) as [$key, $value] | if $key != "" and $value != "" then .[$key] = $value else . end )' | jq --argjson env_vars - '. += $env_vars' src/assets/config.json > temp.json && mv temp.json src/assets/config.json jq . src/assets/config.json
额外提示
- 如果环境变量包含特殊字符(如引号、反斜杠),可能需要对
value做转义处理,演示环境下可暂时忽略; - 建议只处理特定前缀的环境变量(比如以
APP_开头的),避免将系统环境变量(如PATH、HOME)写入配置文件,只需在循环或jq处理时添加过滤逻辑即可。
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

