最简命令是curl -s -o /dev/null -w "%{http_code} %{time_total}s" https://example.com,但需加-m 5 -L -f才健壮;-I不适用因HEAD非真实业务请求且无法准确输出耗时。

直接用 curl -s -o /dev/null -w "%{http_code} %{time_total}s" 就能拿到状态码和总耗时,但要注意它默认不走重定向、DNS失败也不报错——这些都会让你误判服务是否真正常。
只输出状态码和总耗时的最小可行命令
最简写法是:
curl -s -o /dev/null -w "%{http_code} %{time_total}s" https://example.com
说明:
-
-s关闭进度条和错误提示,避免干扰输出 -
-o /dev/null丢弃响应体,否则可能混入 HTML 或 JSON 内容 -
-w是关键,它控制额外输出;%{http_code}和%{time_total}是两个最常用变量 - 注意:这个命令默认不跟随重定向(
301/302会返回原始状态码),如果目标地址有跳转,得加-L
为什么 curl -I 不适合只取状态码+耗时
curl -I 发的是 HEAD 请求,虽然快,但存在三个实际问题:
- 某些服务对 HEAD 做了特殊处理(比如直接返回
200即使后端异常),而 GET 才真实反映业务逻辑 -
-I无法配合-w输出完整耗时字段(%{time_starttransfer}等在 HEAD 下可能不准) - HEAD 请求不触发服务端完整链路(比如鉴权中间件、日志埋点、缓存穿透判断),测出来的时间不具备代表性
必须加的健壮性参数:超时与重定向
线上脚本里裸用 -w 极易被卡住或漏判,建议固定带上:
-
-m 5:总超时 5 秒(含 DNS、连接、传输),防止 hang 死。注意不是--connect-timeout,后者只管建连 -
-L:启用重定向跟踪,否则302返回就是302,不是最终的200 -
-f:遇到非 2xx/3xx 状态码时让命令返回非 0 退出码,方便 shell 判断:if ! curl -sf ...; then echo "fail"; fi
组合起来就是:
curl -sf -m 5 -L -o /dev/null -w "%{http_code} %{time_total}s" https://api.example.com/health
想看更细的阶段耗时?别硬塞进一行输出
虽然 -w 支持 %{time_namelookup}、%{time_connect}、%{time_starttransfer} 等十多个字段,但全打在一行里可读性差,也难解析。建议:
- 调试时用多行格式,例如:
-w "DNS:%{time_namelookup}s\nCONN:%{time_connect}s\nTTFB:%{time_starttransfer}s\nTOTAL:%{time_total}s" - 自动化监控场景下,把格式写进文件再引用:
curl -w "@format.txt" ...,避免命令行过长出错 - 注意
%{time_appconnect}在 HTTP 不走 TLS 时为 0,不要拿它和%{time_connect}盲对比
真正容易被忽略的是:curl 的时间字段全部基于本地系统时钟,且不校准 NTP 偏移。如果服务器和本机时间差 >1s,%{time_starttransfer} 可能出现负值——这时得先检查 ntpq -p,而不是怀疑 curl 有问题。











