curl 返回 0,接口就成功了吗?用 --fail-with-body 分清 HTTP 错误

 2天前     24  

文章目录

自动化脚本里,curl 没报错、退出码还是 0,很容易让人以为接口成功了。我用一个只在本机运行的模拟 HTTP 服务试了试:服务返回 404 和 503,普通 curl 依然返回 0。

这不是 curl 隐瞒错误,而是“传输完成”和“拿到了业务需要的响应”不是一回事。官方文档明确说明:curl 默认不把 HTTP 响应状态码当作失败依据。[2]

一个小实验,分清两层结果

这次使用 curl 8.5.0,模拟响应正文只是固定字符串,没有访问真实业务接口。我对 200、404、503、302 四种状态,分别跑了普通请求、--fail 和 --fail-with-body,共十二组。

  • 200:三种方式都返回 0,保留响应正文。
  • 404、503:普通请求返回 0;加任一失败选项后,返回 22。
  • 错误正文:--fail 不输出;--fail-with-body 保留。
  • 302:本次没有跟随重定向,三种方式都返回 0,并不代表已经取得最终页面。

脚本里,我更愿意显式选择失败语义

如果既想让 HTTP 错误影响退出码,又想保留服务端给的错误说明,可以用:

curl --silent --show-error --fail-with-body --output response.json "$url"

$url 是你已经核对的目标地址;文件名不保证里面一定是 JSON。这里 --silent 关闭进度输出,--show-error 保留 curl 的错误提示;--fail-with-body 则让 400 及以上响应返回错误,同时保留正文。[1] 这个选项从 curl 7.76.0 加入[1],旧环境先检查 curl --version。

保留正文也有代价:请求失败时,response.json 可能装着错误页面或错误对象。后续步骤必须先判断退出状态,不能因为文件存在就直接当成功数据处理。若不需要错误正文,可以改用 --fail;两者不要同时使用。[2]

加了开关,还不等于业务验收通过

本次的 302 就是反例:失败选项并不要求响应必须是 200,也不自动证明拿到了目标资源。至于响应为 200、正文却写着“操作失败”的接口,更要继续检查内容和业务状态,不能只看退出码。

curl 官方还特别提醒,--fail 在涉及认证的某些场景中并非万无一失,401、407 等响应可能漏过。[2] 认证接口应另核实际状态与返回内容,而不是把一个参数当成完整错误处理。

这次实验给我的提醒很简单:给自动化设置成功条件时,至少分开看命令退出状态、HTTP 状态、返回内容。前一层通过,只是可以继续检查下一层,不是后面都自动通过。

本文为 AI 辅助整理的原创合成实验;实验于2026年10月19日完成;2026年10月20日复核 curl 官方选项说明。未测试认证、重试及真实业务接口。

一手来源

版权声明:leif 发表于 2天前,共 1156 字。
转载请注明:curl 返回 0,接口就成功了吗?用 --fail-with-body 分清 HTTP 错误 | 虎娃博客

暂无评论

暂无评论...