暗色模式

curl 命令行:从文件下载到 HTTP 接口调试

技术教程
2026-08-12
12
0
本文要点
  • curl 是 Linux 下最通用的命令行 HTTP 客户端,既能下载文件,也能调试接口,几乎所有发行版都预装
  • 下载用 curl -o 文件名 网址,配合 -w 可输出耗时、大小、速度等传输统计
  • curl -I 只取响应头,配合 -o /dev/null -w "%{http_code}" 可快速查看状态码
  • 调试接口用 -X POST 指定方法、-H 加请求头、-d 传数据,输出 JSON 可接 jq 格式化阅读
  • 所有命令均在 Ubuntu 24.04 演示服务器上真实执行验证

为什么需要 curl

日常运维中,"和 HTTP 打交道"几乎是每天必做的事:程序要下载安装包、脚本要调用别人的接口、排查问题时要看某个服务返回了什么。浏览器只能看页面,而 curl 能让你在命令行里完整控制一次 HTTP 请求——指定方法、加请求头、传数据、查看原始响应,它是脚本和运维场景里的瑞士军刀。

curl 的名字来自 "Client for URL",项目由 Daniel Stenberg 发起,如今几乎所有主流操作系统都内置了它。它和 wget 的定位略有不同:wget 专注下载,curl 更侧重"发一次请求看一次响应",所以调试接口首选 curl。完整参数可参考 curl(1) 手册页

下载文件:-o 与 -w 统计

最简单的用法是 curl -o 保存文件名 网址,把响应内容存成本地文件。加上 -w 参数,还能在结束时打印一行传输统计——格式串里 %{http_code} 是状态码、%{size_download} 是下载字节数、%{time_total} 是总耗时。

在演示服务器上实测下载一个 1MB 的测试文件:

curl 下载文件与 -w 传输统计

图中执行了三条命令:

  1. cd /tmp 切到临时目录,避免污染家目录。
  2. curl -sS -o demo.bin -w "HTTP %{http_code} | saved %{size_download} bytes in %{time_total}s" https://speed.cloudflare.com/__down?bytes=1000000-s 静默(不显示进度条),-S 让出错时仍能显示错误信息;-o demo.bin 把内容存为 demo.bin-w 打印统计,输出 HTTP 200 | saved 1000000 bytes in 0.086560s——状态码 200,成功下载 1000000 字节,耗时约 0.09 秒。
  3. ls -lh demo.bin 确认文件存在,大小显示 977K(1000000 字节换算成 KiB 约 977K)。
-w 的统计格式串很灵活,除了上面三个,还有 %{speed_download}(下载速度)、%{time_connect}(建立连接耗时)、%{redirect_url}(重定向地址)等,适合写进脚本里做健康检查。

-O(大写)与 -o 不同:-O沿用 URL 末尾的文件名作为保存名,适合文件名明确的下载;-o 则完全由你指定保存名。

查看响应头与状态码

排查问题时,先看响应头往往比看正文更快。curl -I 网址 只发出 HEAD 请求,仅返回响应头,不下载正文:

curl -I 查看响应头与 -w 查看状态码

图中展示了三类操作:

  1. curl -sI --max-time 8 https://example.com-I 只取响应头,--max-time 8 限制总耗时 8 秒防止卡住。返回的头部信息很有用:第一行 HTTP/2 200 是协议版本和状态码,content-type: text/html 说明返回的是 HTML 页面,server: cloudflare 表示经过 CDN,cf-ray 是 Cloudflare 的节点标识(末尾 -HKG 表示香港节点)。
  2. curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8800/api/users-o /dev/null 丢弃正文只关心状态码,配合 -w 输出 200
  3. 同理请求一个不存在的路径 /nope,状态码输出 404

这个 -o /dev/null -w "%{http_code}" 组合是脚本里检测服务健康度的标准写法,一条命令就能拿到"通不通、对不对"的答案。

调试 HTTP 接口:方法、请求头与 JSON

curl 不只是下载工具,更是接口调试利器。完整的请求控制需要三个参数配合:-X 指定请求方法(GET/POST/PUT/DELETE 等)、-H 添加请求头、-d 携带请求体数据。

为了演示,我在演示服务器上起了一个本地测试 API(监听 8800 端口,返回 JSON)。注意:-s 会把输出原样打到终端,而 HTTP 接口返回的往往是压缩成一行或缩进凌乱的 JSON,直接看很难读——所以下面把 curl 的输出用管道接到 jq .,让 JSON 格式化并高亮:

curl 调试 JSON 接口:GET 与 POST

图中两条命令:

  1. GET 请求curl -s http://127.0.0.1:8800/api/users | jq .,接口返回一个用户列表 JSON,经 jq 格式化后清晰可见三个用户 alicebobcarol 以及 total: 3
  2. POST 请求curl -s -X POST http://127.0.0.1:8800/api/users -H "Content-Type: application/json" -d '{"name":"dave","age":30}' | jq .-X POST 声明方法为 POST,-H "Content-Type: application/json" 告诉服务端请求体是 JSON,-d 携带数据。测试 API 把收到的数据原样返回,jq 格式化后显示 received 里正是我们提交的 name: daveage: 30
-d 会默认把请求方法改成 POST(即使不加 -X POST 也一样),-X 主要是显式声明、也用于 PUT/DELETE 等。GET 请求带查询参数可以直接拼在 URL 里,如 http://127.0.0.1:8800/api/users?page=2;请求体过大或内容复杂时,-d @文件 可以从文件读取请求体。

日常排障常用参数速查

参数作用
-o 文件名保存响应到指定文件
-O按 URL 末尾文件名保存
-s静默模式,不显示进度条(配合 -S 出错时仍报错)
-I只请求响应头(HEAD)
-X 方法指定请求方法(GET/POST/PUT/DELETE)
-H "键: 值"添加自定义请求头,可多次使用
-d "数据"发送请求体(默认转成 POST),-d @文件 从文件读取
-w "格式串"结束后打印传输统计(%{http_code}%{time_total} 等)
--max-time 秒限制请求总耗时,防止脚本卡死
-L自动跟随重定向(默认不跟)
-k跳过 SSL 证书校验(仅测试环境使用)

三个高频场景

场景一:脚本健康检查。 定时任务里检测服务是否存活,状态码非 200 就报警:

code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 https://blog.astarry.cn/)
[ "$code" = "200" ] && echo "服务正常" || echo "服务异常: $code"

场景二:调用带认证的接口。 接口需要 token 时,用 -H 加 Authorization 头:

curl -s https://api.example.com/v1/orders \
  -H "Authorization: Bearer eyJhbGciOi..." \
  -H "Accept: application/json" | jq .

场景三:下载并解压。 一条命令下载压缩包并立即解压,比如拉取发布包:

curl -sL -o app.tar.gz https://example.com/app-latest.tar.gz
tar xzf app.tar.gz

总结

curl 的核心心智模型很简单:一次请求 = 方法(-X)+ 请求头(-H)+ 请求体(-d)+ 输出处理(-o/-w/管道)。下载文件时用 -o 定名、-w 看统计;排查时用 -I 看响应头、-o /dev/null -w "%{http_code}" 看状态码;调试接口时组合 -X/-H/-d,再用 jq 把 JSON 输出格式化。

再配合 --max-time 防卡死、-L 跟随重定向、-k 跳过证书校验,基本能覆盖日常 90% 的 HTTP 排障和脚本需求。想深入可以看 curl 官方文档curl(1) 手册页

发表评论

暂无评论,快来抢沙发吧!