0

Shell脚本curl重定向结果转JSON:3套实战方案让巡检数据结构化

2026.06.05 | youres | 22次围观

前言:为什么要把curl重定向结果转成JSON?

日常运维和网站巡检中,我们经常用curl检测重定向链路。但原始输出是一行文本,批量检测几百个URL时,肉眼看了头疼。把结果转成JSON格式后,不仅能直接对接日志系统、数据库,还能用jq做二次分析,效率提升不是一星半点。

本文从实战出发,给你3套成熟方案,从基础到进阶,覆盖单URL检测、批量检测、再到结构化输出,看完就能直接用在项目里。

方案一:curl -w 单变量输出配合jq拼接JSON

这是最简单直接的方式。curl的-w参数支持输出多个变量,我们用jq把这些变量包装成JSON对象。

核心命令

curl -s -o /dev/null -w '%{url_effective}\n%{num_redirects}\n%{http_code}\n%{time_total}' \
  -L 'https://example.com' | \
  jq -R -s 'split("\n") | {
    url: .[0],
    redirects: (.[1] | tonumber),
    status_code: (.[2] | tonumber),
    time: (.[3] | tonumber)
  }'

执行后直接输出结构化JSON:

{
  "url": "https://example.com/",
  "redirects": 1,
  "status_code": 200,
  "time": 0.543
}

要点解析

  • -s -o /dev/null:静默模式,丢弃响应体,只关心状态和重定向信息
  • -w格式化输出:用\n分隔每个变量,方便后续解析
  • jq -R -s:-R按行读取原始输入,-s把所有行合并成一个字符串再解析

方案二:curl -w 多变量直接输出JSON格式

如果不想依赖jq,可以直接在-w里用JSON格式拼接输出。这种方式兼容性更好,不装jq也能用。

核心命令

curl -s -o /dev/null -w '{"url":"%{url_effective}","redirects":%{num_redirects},"http_code":%{http_code},"time_total":%{time_total},"time_redirect":%{time_redirect},"time_connect":%{time_connect}}' \
  -L 'https://example.com'

输出:

{"url":"https://example.com/","redirects":1,"http_code":200,"time_total":0.543,"time_redirect":0.123,"time_connect":0.045}

注意事项

  • URL中的引号问题:如果最终URL包含双引号,JSON会格式错误。解决方法是用jq -R .做一次清理,或用sed替换特殊字符
  • 浮点数精度:curl时间变量直接拼接时是裸数字(如0.543),JSON标准允许这样做,不需要额外加引号
  • 变量列表:常用的还有url_redirectsize_downloadspeed_download等,按需添加

方案三:Shell脚本批量检测+JSON数组输出

这是生产环境最常用的方式。从URL列表文件读取,逐个检测,最终输出一个完整的JSON数组。

完整脚本

#!/bin/bash
# curl重定向批量检测脚本 - JSON数组输出
# 用法:./check_redirects.sh urls.txt

URL_FILE="${1:-urls.txt}"
RESULTS="["
FIRST=true

while IFS= read -r url; do
  [ -z "$url" ] && continue
  [ "${url:0:1}" = "#" ] && continue

  result=$(curl -s -o /dev/null -w '{"url":"%{url_effective}","redirects":%{num_redirects},"http_code":%{http_code},"time_total":%{time_total},"time_redirect":%{time_redirect},"error":false}' \
    -L --max-time 10 "$url" 2>&1)

  http_code=$(curl -s -o /dev/null -w '%{http_code}' -L --max-time 10 "$url" 2>&1)

  # 检查是否超时或连接失败
  if [ "$http_code" = "000" ]; then
    result="{\"url\":\"$url\",\"redirects\":0,\"http_code\":0,\"time_total\":0,\"error\":true,\"error_msg\":\"connection_failed\"}"
  fi

  if [ "$FIRST" = true ]; then
    RESULTS="$RESULTS$result"
    FIRST=false
  else
    RESULTS="$RESULTS,$result"
  fi

  # 避免请求过快
  sleep 0.2
done < "$URL_FILE"

RESULTS="$RESULTS]"
echo "$RESULTS" | jq . 2>/dev/null || echo "$RESULTS"

URL列表文件格式(urls.txt)

# 网站巡检列表
https://example.com
https://google.com
https://github.com
https://your-site.cn/about

输出示例

[
  {
    "url": "https://example.com/",
    "redirects": 1,
    "http_code": 200,
    "time_total": 0.543,
    "time_redirect": 0.123,
    "error": false
  },
  {
    "url": "https://github.com/",
    "redirects": 0,
    "http_code": 200,
    "time_total": 0.321,
    "time_redirect": 0.000,
    "error": false
  }
]

进阶技巧:配合xargs并行加速

几百个URL逐个检测太慢?用xargs开启并行:

cat urls.txt | grep -v '^#' | xargs -P 10 -I {} \
  bash -c 'curl -s -o /dev/null -w "{\"url\":\"%{url_effective}\",\"redirects\":%{num_redirects},\"http_code\":%{http_code},\"time\":%{time_total}}" -L --max-time 10 "{}" 2>&1' \
  | jq -s .

-P 10表示同时10个并发,jq -s .把多行JSON合并成数组。注意并发数不要太大,避免被目标服务器限流。

实战建议

  • 超时设置:生产环境务必加--max-time 10,避免单个URL卡住整个脚本
  • 错误处理:状态码为000说明连接失败,要做特殊标记
  • 输出美化:终端调试用jq .美化输出,写入文件直接保存原始JSON即可
  • 定时巡检:配合cron定时执行,JSON结果追加到日志文件,方便后期对比分析
  • 告警对接:JSON格式天然适合对接钉钉、企业微信的Webhook告警

总结

把curl重定向检测结果转成JSON,核心就是三个思路:curl -w输出+jq解析curl -w直接拼接JSONShell脚本批量输出JSON数组。根据你的场景选一个就好——单次调试用方案一,快速输出用方案二,批量巡检用方案三。

相关文章推荐

版权声明

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

发表评论