如何用jq将新机器IP条目安全添加到JSON配置文件?
多机器管理项目JSON更新脚本问题解决
问题背景
我正在开发一个多机器管理项目,机器的用户名与IP存储在JSON对象中,现有JSON结构如下:
{ "a.b.c.d" : { "visible" : true, "color" : "rgb(0, 255, 192)", "user" : "ubuntu", // 可选字段 "address" : "a.b.c.d", "label" : "VPS-Box" // 可选字段 }, "a.b.c.d" : { "visible" : true, "color" : "rgb(125, 255, 0)", "address" : "a.b.c.d" } }
需要实现一个基础监听脚本,接收客户端通过Telnet发送的公网IP,将其按照以下格式添加到上述JSON文件中:
"nc_value" : { "visible" : true, "color" : "rgb(0, 253, 255)", "user" : "REDACTED", "address" : "nc_value" }
之前尝试的脚本无法正确更新JSON,还存在损坏文件的风险,最近的尝试代码如下:
#!/bin/bash while true; do received_data=$(nc -l -p 1337 | tr -d ' ') # 移除接收数据中的空格 echo "$received_data" >> /nc-log.txt # 记录日志验证接收是否正确 # 检查接收数据是否为合法IP地址 if [[ $received_data =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then # 构造JSON条目 new_entry="{\"visible\": true, \"color\": \"rgb(0, 253, 255)\", \"user\": \"REDACTED\", \"address\": \"$received_data\"}" # 将新条目添加到Machines.json jq ". += {\"$received_data\": $new_entry}" /Machines.json > tmp.json && mv tmp.json /Machines.json fi done
问题分析
原脚本存在两个核心问题:
nc监听逻辑缺陷:$(nc -l -p 1337)会等待连接关闭才返回数据,循环中重复执行会导致监听异常,无法处理连续的IP输入。- JSON拼接风险:手动构造
new_entry字符串容易出现转义错误,直接传入jq时可能导致JSON语法失效,损坏原文件。
修正后的解决方案
使用jq原生语法构造JSON条目,避免手动拼接字符串,同时优化nc的监听逻辑,确保JSON更新的原子性:
#!/bin/bash JSON_FILE="/Machines.json" LOG_FILE="/nc-log.txt" LISTEN_PORT=1337 # 初始化JSON文件:若不存在则创建空对象 if [ ! -f "$JSON_FILE" ]; then echo "{}" > "$JSON_FILE" fi while true; do # 读取一行输入(处理Telnet发送的单条IP,去除空格、换行符) received_data=$(nc -l -p "$LISTEN_PORT" | head -n 1 | tr -d ' \r\n') echo "$(date): 接收数据: $received_data" >> "$LOG_FILE" # 校验IPv4格式 if [[ "$received_data" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then # 用jq的变量传递功能构造并插入新条目,保证JSON语法合法 jq --arg ip "$received_data" \ '.[$ip] = { "visible": true, "color": "rgb(0, 253, 255)", "user": "REDACTED", "address": $ip }' "$JSON_FILE" > "$JSON_FILE.tmp" && mv "$JSON_FILE.tmp" "$JSON_FILE" echo "$(date): 成功将IP $received_data 添加到JSON" >> "$LOG_FILE" else echo "$(date): 无效IP格式: $received_data" >> "$LOG_FILE" fi done
关键改进点
jq变量传递:通过--arg传递IP变量,完全避免手动转义JSON字符串,确保生成的内容语法合规。- 原子文件更新:先写入临时文件,再替换原文件,防止脚本中途中断导致JSON损坏。
- 严谨的IP校验:优化正则表达式校验IPv4格式,同时去除输入中的换行、回车符,避免无效字符干扰。
- 日志增强:添加时间戳,便于后续排查问题。
- 文件初始化:自动创建空JSON对象,避免
jq因文件不存在报错。
额外优化建议
- 避免重复条目:若需要防止相同IP重复添加,可修改
jq命令增加判断:jq --arg ip "$received_data" \ 'if has($ip) then . else .[$ip] = { "visible": true, "color": "rgb(0, 253, 255)", "user": "REDACTED", "address": $ip } end' "$JSON_FILE" > "$JSON_FILE.tmp" && mv "$JSON_FILE.tmp" "$JSON_FILE" nc兼容性:部分系统的nc参数不同(如BSD版本用nc -l 1337而非-p),若脚本运行异常可调整监听参数。- 权限检查:确保脚本拥有读写
$JSON_FILE和$LOG_FILE的权限。
内容的提问来源于stack exchange,提问作者dankatapich
相关产品推荐
相关产品推荐

