本文要点
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 的测试文件:

图中执行了三条命令:
cd /tmp切到临时目录,避免污染家目录。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 秒。ls -lh demo.bin确认文件存在,大小显示977K(1000000 字节换算成 KiB 约 977K)。
-w的统计格式串很灵活,除了上面三个,还有%{speed_download}(下载速度)、%{time_connect}(建立连接耗时)、%{redirect_url}(重定向地址)等,适合写进脚本里做健康检查。
-O(大写)与 -o 不同:-O 会沿用 URL 末尾的文件名作为保存名,适合文件名明确的下载;-o 则完全由你指定保存名。
查看响应头与状态码
排查问题时,先看响应头往往比看正文更快。curl -I 网址 只发出 HEAD 请求,仅返回响应头,不下载正文:

图中展示了三类操作:
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表示香港节点)。curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8800/api/users:-o /dev/null丢弃正文只关心状态码,配合-w输出200。- 同理请求一个不存在的路径
/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 格式化并高亮:

图中两条命令:
- GET 请求:
curl -s http://127.0.0.1:8800/api/users | jq .,接口返回一个用户列表 JSON,经jq格式化后清晰可见三个用户alice、bob、carol以及total: 3。 - 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: dave、age: 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) 手册页。
评论 (0)
暂无评论,快来抢沙发吧!