curl 命令完全指南:你真正会用的每一个参数
2026-08-17
curl https://example.com 是地球上装机量最大的 HTTP 客户端,它一直藏在眼皮底下:一个开发者拥有的最好用的调试工具,唯一的短板是围绕它的文档鸿沟。学会十几个参数后,curl 会变成你探测 API、复现 bug、验证修复最快的方式——不用开浏览器,也不用写一次性脚本。这篇文章按你实际需要的顺序讲解这些参数。
curl 命令的解剖
一条 curl 调用等于一个 URL 加若干个参数:
curl [参数] URL
默认情况下 curl 发送 GET 请求并把响应体写到标准输出。参数就是把它从裸命令变成完整 HTTP 客户端的东西——而且参数之间没有顺序要求,同一条命令可以有好几种写法。如果记不清某个参数的行为,curl --help 列出全部,curl --help all 展示完整手册。
读取响应:-i、-I、-L、-s
光有响应体往往说明不了问题。三个参数让响应变得可读:
curl -i https://api.example.com/users # 连同响应头一起输出
curl -I https://api.example.com/users # 只发 HEAD:只要响应头,不要响应体
curl -L https://example.com/login # 跟随重定向(3xx)
-i/--include——在响应体上方打印响应状态行和响应头。请求”没生效”时第一个要加的就是它,因为答案往往就藏在状态码里。-I/--head——发送 HEAD 请求(含义见 HTTP 方法指南),只打印响应头。用来在不下载的前提下检查资源是否存在、多大、什么类型,非常高效。-L/--location——在每个重定向地址上重新发起请求。没有它,301/302 只打印重定向响应就停了——“为什么调 API 返回了一堆 HTML?“的经典迷案就是这么来的。-s/--silent——隐藏进度条。配合-S(--show-error)让错误仍然显示:-sS是脚本里安静又信息充足的组合。
请求头与方法:-H、-X
自定义请求头和显式方法,是 curl 开始像个真正的客户端的地方:
curl -X POST https://api.example.com/users
curl -H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
https://api.example.com/users/7
-H "名称: 值"——设置一个请求头。要多设几个就重复这个参数;给-H传空值可以去掉某个默认头。-X METHOD——设置 HTTP 方法。常见的坑:curl 的-X POST只覆盖方法本身,不会触发-d或-F隐含的那些行为(比如自动设Content-Type)。实践里你很少需要-X——发-d就已经隐含 POST,-F隐含 multipart POST——但你经常需要的是-X PUT、-X PATCH、-X DELETE。
发送数据:-d、JSON、—data-binary
curl -d "name=ada&role=admin" https://api.example.com/users # 表单编码
curl -H "Content-Type: application/json" \
-d '{"name": "ada", "role": "admin"}' \
https://api.example.com/users # JSON
curl --data-binary @body.json https://api.example.com/users # 原始文件体
-d "key=value"/--data——发送表单编码数据(application/x-www-form-urlencoded),并隐含 POST。多个-d会自动用&拼接。- 配上
-H "Content-Type: application/json"和一段 JSON 字符串,同一个-d就变成了 JSON 请求体——这是你以后每一次 API 调用的主力写法。 --data-binary @file——把文件内容原样作为请求体发送(不剥离换行符)。请求体来自文件时,前面都要加@。- 想看 curl 到底构造了什么请求,加
-v(见下文)——请求体和请求头会原样可见。
文件:-o、-O、-F、-T
curl -o report.pdf https://example.com/report.pdf # 保存到指定文件名
curl -O https://example.com/report.pdf # 用远程文件名保存
curl -F "avatar=@photo.png" https://example.com/upload # multipart 文件上传
curl -F "avatar=@photo.png;type=image/png" https://example.com/upload
curl -T backup.zip https://example.com/uploads/ # 用 PUT 上传文件
-o file/-O——把响应体写进文件而不是标准输出。用-o /dev/null可以丢弃大响应体,同时保留可见的响应头。-F "字段=@文件"——multipart/form-data 上传,等价于 HTML 里的<input type="file">表单。加;type=可以强制指定上传部分的 Content-Type。-T file/--upload-file——把文件内容用 PUT 发送到该 URL。配合下载参数可以快速做一次备份往返。
Cookies、认证与会话
curl -b "session=abc123" https://example.com/me # 手动发送一个 cookie
curl -c cookies.txt https://example.com/login # 把 cookie 存进 jar
curl -b cookies.txt https://example.com/me # 之后重放
curl -u user:pass https://api.example.com/private # HTTP Basic 认证
curl -H "Authorization: Bearer $TOKEN" https://api.example.com/private
-b——发送 cookies,可以是一条内联的"name=value"字符串,也可以来自文件(cookie jar / Netscape 格式)。-c把响应设置的 cookies 写进 jar。- 经典的会话三步:先用
-c捕获登录 cookie,再用-b在后续请求中重放——终端版的”已登录浏览器标签页”。 -u user:pass——HTTP Basic 认证(请求头里 base64 编码)。令牌类 API 更常用Authorization: Bearer请求头。
调试:-v、-w、-f
curl -v https://api.example.com/users # verbose:完整的请求/响应
curl -w "\n%{http_code} in %{time_total}s\n" https://api.example.com/users
curl -f https://api.example.com/users/404 # HTTP 出错时以非零码退出
-v/--verbose——打印完整的请求行、请求头、TLS 握手细节和响应头。别的办法都不奏效时,-v让你亲眼看到线上到底传输了什么。--trace-ascii -连原始字节都显示。-w '格式'/--write-out——在响应之后打印附加信息。%{http_code}、%{time_total}、%{size_download}是衡量 API 延迟或确认状态码时最常用的三个,不用去解析响应体。%{redirect_url}会显示 3xx 想让你去哪。-f/--fail——让 curl 在收到 HTTP 4xx/5xx 时以非零码(22)退出,而不是打印错误页然后”成功”。对需要确认请求确实失败的脚本来说是必备参数。
超时与重试
curl --connect-timeout 5 https://api.example.com # TCP 连接卡住则快速失败
curl -m 30 https://api.example.com/slow # 总时长的硬上限
curl --retry 3 --retry-delay 2 https://api.example.com/jittery
--connect-timeout只限定连接阶段——对连不上的主机快速失败用它。-m/--max-time限定整个操作的时长——对付挂起端点的护栏。--retry N在瞬时失败时重试(带间隔)。要注意:如果方法非幂等,重试可能重放一次 POST——为什么这很要紧,见 HTTP 方法指南。
实用建议
- 从最小开始,按需累加: 先
curl -i,需要时加-L跟重定向,确定请求形状后再加-H和-d。 - 别把密钥贴进聊天记录——把令牌放进环境变量(
$TOKEN)再引用,就像上面的示例那样。 - 把 curl 变成代码: 请求调试通了之后,curl 转代码工具能把这条命令直接转成 JavaScript
fetch、Python、Go 等语言——不用手翻。 - 顺手查一下刚收到的状态码:用 HTTP 状态码速查——知道 405 是”方法用错了”(而
Allow头会列出正确的方法)能解开大部分 API 谜题。 - 把最常用的写法存成 shell 别名或小脚本;一个
cget()/cjson()封装就能覆盖 90% 的日常 API 工作。
速查表
curl -i URL——看状态码和响应头。curl -L URL——跟随重定向。curl -sS URL——安静但显示错误。-H "名称: 值"设请求头,要多个就重复;-X PUT/-X PATCH/-X DELETE换方法。-d "k=v"= 表单 POST;-d '{"json":...}'+-H "Content-Type: application/json"= JSON POST;--data-binary @file= 原始请求体。-o file保存,-O按远程名保存,-F "字段=@文件"multipart 上传,-T filePUT 上传。-b发 cookies,-c存 cookies,-u user:passBasic 认证,Bearer 用-H "Authorization: ..."。-v完整线上转储,-w '%{http_code}'打印状态码,-fHTTP 出错即失败。--connect-timeout、-m(总时长)、--retry N让不稳定的请求不至于永远挂起。