You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Bash脚本中处理Curl请求失败并跳过故障服务器

处理Bash Curl请求中的故障服务器跳过问题

你的问题核心是只要有一台服务器返回无效JSON或无响应,整个输出的JSON文件就会损坏甚至为空——这是因为原脚本没有对curl请求结果做任何校验,直接用jq解析失败响应会触发错误,甚至中断后续输出;同时原有的逗号处理逻辑也会因为跳过服务器而破坏JSON格式。

下面是改进后的脚本,附带详细的优化说明:

改进后的完整脚本

#!/bin/bash
CONFIG=config.json
jsondata=data.json

# 初始化JSON文件的头部结构
echo '{ "success": "OK", "servers": {' > "$jsondata"

# 标记是否是第一个要写入的服务器条目,解决逗号位置问题
first_entry=true

# 遍历配置文件中的所有服务器键名
jq -r '.servers|keys[]' "$CONFIG" | while read key ; do
    # 从配置文件中提取当前服务器的IP和端口(请根据你的config.json实际结构调整)
    # 假设config.json结构示例:{"servers": {"server1": {"ip": "192.168.1.10", "port": "8080"}, ...}}
    IP=$(jq -r ".servers[\"$key\"].ip" "$CONFIG")
    PORT=$(jq -r ".servers[\"$key\"].port" "$CONFIG")
    HTTP="http" # 如果需要支持HTTPS,可以改成"https"或从配置中读取

    # 执行curl请求:-s静默模式,-f确保HTTP错误时返回非0,-w捕获HTTP状态码
    RESPONSE=$(curl -s -f -w "%{http_code}" "$HTTP://$IP:$PORT/api")
    # 分离HTTP状态码和响应体(状态码是最后3位)
    HTTP_STATUS=${RESPONSE: -3}
    RESPONSE_BODY=${RESPONSE%???}

    # 双重校验:HTTP状态码正常(200-299)且响应体是有效JSON
    if [ "$HTTP_STATUS" -ge 200 ] && [ "$HTTP_STATUS" -lt 300 ] && echo "$RESPONSE_BODY" | jq -e . >/dev/null 2>&1; then
        # 如果不是第一个条目,先写入逗号保证JSON格式合法
        if [ "$first_entry" = false ]; then
            echo "," >> "$jsondata"
        fi
        first_entry=false

        # 解析需要的字段并写入JSON文件
        DATA1=$(echo "$RESPONSE_BODY" | jq '.data1')
        DATA2=$(echo "$RESPONSE_BODY" | jq '.data2')
        echo "  \"$key\": {" >> "$jsondata"
        echo "    \"data1\": $DATA1," >> "$jsondata"
        echo "    \"data2\": $DATA2" >> "$jsondata"
        echo "  }" >> "$jsondata"

        # 输出成功日志到stderr,不影响JSON文件内容
        echo "[INFO] Successfully fetched data from $key ($IP:$PORT)" >&2
    else
        # 输出错误日志到stderr,方便排查问题
        echo "[ERROR] Failed to get valid data from $key ($IP:$PORT). HTTP Status: $HTTP_STATUS, Response: $RESPONSE_BODY" >&2
    fi
done

# 完成JSON文件的尾部结构
echo "} }" >> "$jsondata"

echo "[INFO] Final JSON file generated at $jsondata" >&2

关键优化点说明

  • curl请求的可靠性校验
    -f参数让curl在HTTP状态码为4xx/5xx时直接返回非0错误码,同时通过-w "%{http_code}"捕获具体状态码,方便区分是网络不通还是服务器返回业务错误。
  • JSON有效性验证
    使用jq -e .检查响应体是否为合法JSON,-e参数会让jq在解析失败时返回非0,结合>/dev/null 2>&1隐藏冗余输出,只关注校验结果。
  • JSON格式的稳定性
    first_entry变量替代原脚本的i计数来控制逗号输出,即使跳过多台故障服务器,也能保证生成的JSON始终是合法格式,不会出现多余或缺失的逗号。
  • 错误日志分离
    所有日志信息(成功/失败)都输出到标准错误流(>&2),不会污染JSON文件内容,同时方便你运行脚本时查看哪些服务器出了问题。
  • 配置读取优化
    补充了从config.json中提取IP和端口的逻辑,原脚本中这两个变量是硬编码的,现在更灵活适配你的配置文件(请根据实际的config.json结构调整jq提取语句)。

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

火山引擎 最新活动