You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用jq更新JSON字段?Bootstrap脚本状态记录问题

问题与修复方案

需求说明

我需要实现一个bootstrap脚本,每次运行后将退出状态记录到JSON文件中,要求:

  • 首次运行(文件不存在):创建JSON文件并添加布尔类型的node_bootstrap_status字段
  • 后续运行(文件已存在):仅更新node_bootstrap_status的布尔值,保留文件中已有的其他字段

原脚本问题

原脚本在首次运行时正常工作,但后续运行会清空JSON文件的所有内容,原脚本代码如下:

exit_code=1

node_info_file="/etc/node_info.json"


if [[ -f $node_info_file ]]; then
  # /etc/node_info.json exists
  echo "${node_info_file} exists"
  if [ $exit_code = 0 ]; then
    cat $node_info_file | jq --argjson node_bootstrap_status true '{"node_bootstrap_status": $node_bootstrap_status}' > $node_info_file
  else
    cat $node_info_file | jq --argjson node_bootstrap_status false '{"node_bootstrap_status": $node_bootstrap_status}' > $node_info_file
  fi  
else
  # /etc/node_info.json does NOT exists
  echo "${node_info_file} does not exist"
  touch ${node_info_file}
  if [ $exit_code = 0 ]; then
    echo '{}' | jq --argjson node_bootstrap_status true '{"node_bootstrap_status": $node_bootstrap_status}' > $node_info_file
  else
    echo '{}' | jq --argjson node_bootstrap_status false '{"node_bootstrap_status": $node_bootstrap_status}' > $node_info_file
  fi  
fi

问题根源

  1. 字段覆盖而非更新:jq命令'{"node_bootstrap_status": $node_bootstrap_status}'直接生成仅包含目标字段的新JSON对象,完全丢弃了原文件中的其他字段。
  2. 文件读写竞态:cat $node_info_file | jq ... > $node_info_file的写法存在问题,shell会先打开目标文件进行写入(清空内容),再执行cat读取文件,此时文件已经是空的,导致jq处理的是空数据。

修复后的脚本

exit_code=1
node_info_file="/etc/node_info.json"

# 将退出码转换为布尔值
bootstrap_status=$([ $exit_code -eq 0 ] && echo "true" || echo "false")

if [[ -f "$node_info_file" ]]; then
    echo "${node_info_file} exists, updating node_bootstrap_status"
    # 使用临时文件避免读写竞态,仅更新指定字段并保留其他内容
    jq --argjson status "$bootstrap_status" '.node_bootstrap_status = $status' "$node_info_file" > "$node_info_file.tmp" && mv "$node_info_file.tmp" "$node_info_file"
else
    echo "${node_info_file} does not exist, creating new file"
    # 创建包含目标字段的新JSON文件
    jq --argjson status "$bootstrap_status" '{node_bootstrap_status: $status}' > "$node_info_file"
fi

关键改进

  • 使用jq的.node_bootstrap_status = $status语法,仅更新指定字段,保留原JSON中的其他内容。
  • 引入临时文件处理写入操作,避免直接覆盖原文件导致的读写竞态问题,同时防止脚本中断时损坏原文件。
  • 简化逻辑,将退出码转布尔值的操作统一提取,减少重复代码。

验证结果

运行脚本后,JSON文件会保留原有字段并更新目标状态,示例结果:

{
  "node_bootstrap_status": false,
  "foo": "bar"
}

内容的提问来源于stack exchange,提问作者Korba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 11:15:37