HandyTools Hub

← 全部指南

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 file PUT 上传。
  • -b 发 cookies,-c 存 cookies,-u user:pass Basic 认证,Bearer 用 -H "Authorization: ..."
  • -v 完整线上转储,-w '%{http_code}' 打印状态码,-f HTTP 出错即失败。
  • --connect-timeout-m(总时长)、--retry N 让不稳定的请求不至于永远挂起。