0

curl批量检测重定向结果JSON模板配置:3个实战方案让巡检数据结构化存储

2026.06.05 | youres | 21次围观

做网站运维的都逃不过一个问题——批量检测重定向。几十上百个URL需要定期巡检,结果怎么存?CSV太原始,HTML报告太重,JSON才是最灵活的选择。今天聊聊怎么用curl的-w参数配合JSON模板,把重定向检测结果结构化输出。

为什么JSON比CSV更适合重定向巡检

CSV的问题在于:重定向链路这种嵌套数据不好表达。一个URL可能经过3跳,每跳有状态码、Location头、耗时,CSV要么挤成一行超长字符串,要么拆成多行关联查询很麻烦。

JSON天然支持嵌套结构,一个URL的所有检测数据可以打包成一个对象,数组存多个URL的结果,jq一行命令就能过滤分析。更重要的是,JSON可以直接对接后续的数据处理——导入数据库、喂给监控平台、API推送,都比CSV顺畅。

方案一:curl -w单行JSON模板

最直接的方式是用curl -w把结果格式化成单行JSON。核心思路是手动拼接JSON字段:

# 检测单个URL的重定向结果,输出JSON
curl -s -o /dev/null -w '{"url":"%{url_effective}","redirects":%{num_redirects},"http_code":%{http_code},"time_total":%{time_total},"time_redirect":%{time_redirect},"remote_ip":"%{remote_ip}"}\n' \
  -L "https://example.com"

输出示例:

{"url":"https://example.com/final-page","redirects":2,"http_code":200,"time_total":0.543,"time_redirect":0.231,"remote_ip":"93.184.216.34"}

几个注意点:

  • 字段值如果是字符串要用引号包裹,数字类型不加引号
  • \n在模板里是换行符,确保每个URL一行
  • 用-s -o /dev/null静默主体内容,只输出-w的格式化结果
  • 配合jq美化输出:curl ... | jq .

批量检测脚本

#!/bin/bash
# 批量检测重定向并输出JSON数组
URLS_FILE="urls.txt"
echo "[" > result.json
first=true
while IFS= read -r url; do
  [ -z "" ] && continue
  if [ "" = true ]; then
    first=false
  else
    echo "," >> result.json
  fi
  curl -s -o /dev/null -w '{"original":"'url'","final":"%{url_effective}","redirects":%{num_redirects},"code":%{http_code},"time":%{time_total}}' \
    -L --max-time 10 "" >> result.json
done < ""
echo "]" >> result.json

这段脚本读取urls.txt中的URL列表,逐个检测后把结果拼接成合法的JSON数组。用jq校验一下:jq . result.json

方案二:curl -w @模板文件方式

当检测字段多的时候,命令行拼字符串容易出错。curl支持-w @文件从文件读取模板,更清晰:

创建模板文件redirect.json.tpl:

{
  "original_url": "https://www.example.com",
  "final_url": "%{url_effective}",
  "redirect_count": %{num_redirects},
  "http_code": %{http_code},
  "response": {
    "dns_time": %{time_namelookup},
    "connect_time": %{time_connect},
    "redirect_time": %{time_redirect},
    "total_time": %{time_total}
  },
  "ssl": {
    "verify_result": %{ssl_verify_result}
  }
}

使用方式:

curl -s -o /dev/null -w @redirect.json.tpl -L "https://example.com"

用sed动态替换URL字段

模板里original_url是固定的,实际使用时需要动态替换。简单做法是用sed:

# 生成动态模板
sed "s|https://www.example.com|url|g" redirect.json.tpl > /tmp/dyn_tpl.txt
curl -s -o /dev/null -w @/tmp/dyn_tpl.txt -L "url"

完整批量脚本:

#!/bin/bash
TPL="redirect.json.tpl"
URLS="urls.txt"
OUT="redirect_report_(date +%Y%m%d).json"
echo "[" > "OUT"
first=true
while IFS= read -r url; do
  [ -z "url" ] &&& continue
  [ "first" = true ] &&& first=false || echo "," >> "OUT"
  sed "s|https://www.example.com|url|g" "TPL" > /tmp/dyn.tpl
  result=(curl -s -o /dev/null -w @/tmp/dyn.tpl -L --max-time 10 "url" 2>/dev/null)
  echo "result" >> "OUT"
done < "URLS"
echo "]" >> "OUT"
rm -f /tmp/dyn.tpl
echo "报告已生成: OUT"

这个方案的优点是模板可维护、字段清晰,缺点是sed替换有注入风险——URL如果含特殊字符可能破坏JSON结构。实际生产环境建议对URL做JSON转义预处理。

方案三:混合输出+jq后处理

如果不想在curl模板里硬拼JSON结构,更稳妥的方式是curl输出原始格式化数据,然后用jq组装:

# curl输出TSV格式,jq转JSON
curl -s -o /dev/null \
  -w "%{url_effective}\t%{num_redirects}\t%{http_code}\t%{time_total}\t%{time_redirect}\n" \
  -L "https://example.com" | \
  jq -Rsn '
    [inputs | split("\t") | .[] | select(length > 0) | 
      . as row |
      {
        final_url: row[0],
        redirects: (row[1] | tonumber),
        http_code: (row[2] | tonumber),
        total_time: (row[3] | tonumber),
        redirect_time: (row[4] | tonumber)
      }
    ]'

批量版本:

#!/bin/bash
OUT="redirect_report.json"
curl -s -o /dev/null \
  -w "%{url_effective}\t%{num_redirects}\t%{http_code}\t%{time_total}\t%{time_redirect}\n" \
  -L --max-time 10 -K urls.txt | \
  jq -Rsn '
    [inputs | split("\t") | .[] | select(length > 0) |
      . as row |
      {
        final_url: row[0],
        redirects: (row[1] | tonumber),
        http_code: (row[2] | tonumber),
        total_time: (row[3] | tonumber),
        redirect_time: (row[4] | tonumber)
      }
    ]' > "OUT"

注意-K参数读取URL列表的格式是url = "https://xxx",每个URL一行。这种方式的好处是JSON结构完全由jq控制,不受curl模板限制,不容易出格式错误。

常用curl -w变量速查

重定向检测中常用的-w变量:

  • url_effective - 最终跳转后的URL
  • num_redirects - 重定向次数
  • http_code - 最终HTTP状态码
  • redirect_url - 查询重定向到的URL(不跟随重定向时使用)
  • time_total - 总耗时(秒)
  • time_redirect - 重定向耗时
  • time_namelookup - DNS解析耗时
  • time_connect - TCP连接耗时
  • ssl_verify_result - SSL证书验证结果(0为通过)
  • remote_ip - 目标服务器IP

实用技巧

1. 并行加速:加xargs -P并行:

xargs -P 10 -I {} curl -s -o /dev/null \
  -w '{"url":"%{url_effective}","code":%{http_code}}\n' \
  -L --max-time 10 {} < urls.txt

2. 异常过滤:用jq筛选有问题的URL:

# 找出状态码非200的
jq '[.[] | select(.http_code != 200)]' result.json

# 找出重定向次数超过3的
jq '[.[] | select(.redirects > 3)]' result.json

# 找出耗时超过2秒的
jq '[.[] | select(.total_time > 2)]' result.json

3. 超时保护:批量检测一定要加--max-time,避免个别慢站点卡住整个脚本。建议设10秒。

总结

三种方案各有适用场景:单行JSON模板适合简单快速检测,@模板文件方式适合字段多且需要维护的场景,混合输出+jq后处理最稳健适合生产环境。选哪个看你的巡检规模和数据处理需求——但不管选哪个,JSON格式化存储都是让重定向巡检数据真正有用的关键一步。

相关阅读

版权声明

本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论