curl - 命令精髓详解 - 图1

curl 是常用的命令行工具,用来请求 Web 服务器。它的名字就是客户端(client)的 URL 工具的意思。
它的功能非常强大,命令行参数多达几十种。如果熟练的话,完全可以取代 Postman 这一类的图形界面工具。

Curl 妙用

使用 curl 执行远程 脚本

例如, 优化 linux 内核参数

  1. bash -c "$(curl -sS https://gitee.com/lwmacct/web-vscode-shell/raw/main/workspace/shell/centos/kernel/sysctl.sh)"

httpbin 测试 HTTP 请求及响应的网站

在介绍curl 之前先, 介绍一个 httpbin 这个网站能测试 HTTP 请求和响应的各种信息,比如 cookie、ip、headers 和登录验证等,且支持 GET、POST 等多种方法,对 web 开发和测试很有帮助。
它用 Python + Flask 编写,是一个开源项目。官方网站:http://httpbin.org/
开源地址:https://github.com/Runscope/httpbin

不带有任何参数时,curl 就是发出 GET 请求。

  1. curl http://httpbin.org/get

上面命令向 http://httpbin.org/get 发出 GET 请求,服务器返回的内容会在命令行输出。

Curl 查询请求各阶段耗时

  1. curl -X GET -w "\ntime_namelookup:%{time_namelookup}\ntime_connect: %{time_connect}\ntime_starttransfer: %{time_starttransfer}\ntime_total: %{time_total}\n" "https://www.baidu.com"

参数说明:

time_namelookup: DNS 服务器域名解析的时间
time_connect: client 发出请求,到 c/s 建立TCP 的时间;里面包括 DNS 解析的时间
time_starttransfer: client 发出请求;到 server 响应发出第一个字节开始的时间;包括前面的2个时间
time_total: 请求发起到链接关闭总耗时

结果示例:

time_namelookup:0.004 (4ms)
time_connect: 0.017
time_starttransfer: 0.137
time_total: 0.137

Curl 选项

-A 参数指定客户端的用户代理标头

即User-Agent。curl 的默认用户代理字符串是curl/[version]。
下面命令将User-Agent改成 Chrome 浏览器。

  1. curl -A 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36' http://httpbin.org/get
  1. {
  2. "args": {},
  3. "headers": {
  4. "Accept": "*/*",
  5. "Host": "httpbin.org",
  6. "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36",
  7. "X-Amzn-Trace-Id": "Root=1-61190e4e-62a4802b04db758c14b9c4a0"
  8. },
  9. "origin": "120.239.31.83",
  10. "url": "http://httpbin.org/get"
  11. }

也可以通过-H参数直接指定标头,更改User-Agent。

  1. curl -H 'User-Agent: php/1.0' http://httpbin.org/get
  1. {
  2. "args": {},
  3. "headers": {
  4. "Accept": "*/*",
  5. "Host": "httpbin.org",
  6. "User-Agent": "php/1.0",
  7. "X-Amzn-Trace-Id": "Root=1-61190f04-40c64b1e70a3f2881a4ec27e"
  8. },
  9. "origin": "120.239.25.220",
  10. "url": "http://httpbin.org/get"
  11. }

-b 参数用来向服务器发送 Cookie。

发送 -c 返回的 cookie 文件 当你阅读这里的时候推荐你先看一下 参数 -c https://www.yuque.com/uuu/shell/curl#fxAgy

  1. curl -b /tmp/curl.cookie http://httpbin.org/get
  1. {
  2. "args": {},
  3. "headers": {
  4. "Accept": "*/*",
  5. "Cookie": "auth=yuque; admin=lwmacct",
  6. "Host": "httpbin.org",
  7. "User-Agent": "curl/7.29.0",
  8. "X-Amzn-Trace-Id": "Root=1-611914b3-36ae5f06080913fc5048b535"
  9. },
  10. "origin": "220.191.56.11",
  11. "url": "http://httpbin.org/get"
  12. }

自定义 cookie 信息

  1. curl -b 'auth=yuque; admin=lwmacct' http://httpbin.org/get
  1. {
  2. "args": {},
  3. "headers": {
  4. "Accept": "*/*",
  5. "Cookie": "auth=yuque; admin=lwmacct",
  6. "Host": "httpbin.org",
  7. "User-Agent": "curl/7.29.0",
  8. "X-Amzn-Trace-Id": "Root=1-611916f2-364f6c43384a4d370f0e176e"
  9. },
  10. "origin": "220.191.56.11",
  11. "url": "http://httpbin.org/get"
  12. }

-c 参数将服务器设置的 Cookie 写入一个文件。

  1. curl -I -c /tmp/curl.cookie http://httpbin.org/cookies/set?admin=lwmacct\&auth=yuque
  1. HTTP/1.1 302 FOUND
  2. Date: Sun, 15 Aug 2021 13:19:10 GMT
  3. Content-Type: text/html; charset=utf-8
  4. Content-Length: 223
  5. Connection: keep-alive
  6. Server: gunicorn/19.9.0
  7. Location: /cookies
  8. Set-Cookie: admin=lwmacct; Path=/
  9. Set-Cookie: auth=yuque; Path=/
  10. Access-Control-Allow-Origin: *
  11. Access-Control-Allow-Credentials: true

-d 参数用于发送 POST 请求的数据体。

使用 -d 参数以后,HTTP 请求会自动加上标头Content-Type : application/x-www-form-urlencoded。并且会自动将请求转为 POST 方法,因此可以省略 -X POST。

  1. curl -X POST -d 'user=lwmacct&password=mima' http://httpbin.org/post
  1. {
  2. "args": {},
  3. "data": "",
  4. "files": {},
  5. "form": {
  6. "password": "mima",
  7. "user": "lwmacct"
  8. },
  9. "headers": {
  10. "Accept": "*/*",
  11. "Content-Length": "26",
  12. "Content-Type": "application/x-www-form-urlencoded",
  13. "Host": "httpbin.org",
  14. "User-Agent": "curl/7.29.0",
  15. "X-Amzn-Trace-Id": "Root=1-61193a64-36544e425e013e452a1583e1"
  16. },
  17. "json": null,
  18. "origin": "220.191.56.11",
  19. "url": "http://httpbin.org/post"
  20. }

-d 参数可以读取本地文本文件的数据,向服务器发送

可以观察一下,下面的的,form 和 上面的示例是一样的

  1. echo 'user=lwmacct&password=mima' > /tmp/curl.post.form
  2. curl -d '@/tmp/curl.post.form' http://httpbin.org/post
  1. {
  2. "args": {},
  3. "data": "",
  4. "files": {},
  5. "form": {
  6. "password": "mima",
  7. "user": "lwmacct"
  8. },
  9. "headers": {
  10. "Accept": "*/*",
  11. "Content-Length": "26",
  12. "Content-Type": "application/x-www-form-urlencoded",
  13. "Host": "httpbin.org",
  14. "User-Agent": "curl/7.29.0",
  15. "X-Amzn-Trace-Id": "Root=1-61193ac8-3cc7234529af14bf13c2221b"
  16. },
  17. "json": null,
  18. "origin": "220.191.56.11",
  19. "url": "http://httpbin.org/post"
  20. }
  1. echo 'user=lwmacct&password=mima' > /tmp/curl.post.form
  2. echo '{"user":"lwmacct","password":"mima"}' > /tmp/curl.post
  3. curl -d '@/tmp/curl.post.form' http://httpbin.org/post

—data-urlencode URL 编码

—data-urlencode参数等同于-d,发送 POST 请求的数据体,区别在于会自动将发送的数据进行 URL 编码。

  1. curl --data-urlencode 'url=https://www.yuque.com/uuu/shell/curl' http://httpbin.org/post
  1. {
  2. "args": {},
  3. "data": "",
  4. "files": {},
  5. "form": {
  6. "url": "https://www.yuque.com/uuu/shell/curl"
  7. },
  8. "headers": {
  9. "Accept": "*/*",
  10. "Content-Length": "52",
  11. "Content-Type": "application/x-www-form-urlencoded",
  12. "Host": "httpbin.org",
  13. "User-Agent": "curl/7.29.0",
  14. "X-Amzn-Trace-Id": "Root=1-61193c3e-7329fd95074983b34d15e1a8"
  15. },
  16. "json": null,
  17. "origin": "220.191.56.11",
  18. "url": "http://httpbin.org/post"
  19. }

好吧, 上面的示例中 --data-urlencode-d 看起来没什么区别,单在床上过程中确实上面的网址确实是被编码成了 https%3A%2F%2Fwww.yuque.com%2Fuuu%2Fshell%2Fcurl

-e 设置 HTTP 的标头Referer,表示请求的来源。

  1. curl -e 'https://www.yuque.com/uuu/shell/curl' http://httpbin.org/get
  1. {
  2. "args": {},
  3. "headers": {
  4. "Accept": "*/*",
  5. "Host": "httpbin.org",
  6. "Referer": "https://www.yuque.com/uuu/shell/curl",
  7. "User-Agent": "curl/7.29.0",
  8. "X-Amzn-Trace-Id": "Root=1-61193d1c-3b3122a20c6101b17d69329c"
  9. },
  10. "origin": "220.191.56.11",
  11. "url": "http://httpbin.org/get"
  12. }

上面命令将Referer标头设为 https://www.yuque.com/uuu/shell/curl
-H参数可以通过直接添加标头Referer,达到同样效果。
curl -H ‘Referer: https://google.com?q=examplehttps://www.example.com

  1. curl -H 'Referer: https://www.yuque.com/uuu/shell/curl' http://httpbin.org/get

-F 文件上传

-F参数用来向服务器上传二进制文件。

  1. curl -F 'file=@/tmp/写真照.png' http://httpbin.org/post
  1. {
  2. "args": {},
  3. "data": "",
  4. "files": {
  5. "file": "data:application/octet-stream;base64,*************上传的是图片,所以被 httpbin 转成 base64 了太长了省略掉吧,*************"
  6. },
  7. "form": {},
  8. "headers": {
  9. "Accept": "*/*",
  10. "Content-Length": "3022",
  11. "Content-Type": "multipart/form-data; boundary=----------------------------30b574e27eaf",
  12. "Host": "httpbin.org",
  13. "User-Agent": "curl/7.29.0",
  14. "X-Amzn-Trace-Id": "Root=1-61193e1b-6c3c3f222b345a4374be3fde"
  15. },
  16. "json": null,
  17. "origin": "220.191.56.11",
  18. "url": "http://httpbin.org/post"
  19. }

上面命令会给 HTTP 请求加上标头Content-Type: multipart/form-data,然后将文件photo.png作为file字段上传。

-F参数可以指定 MIME 类型。

  1. curl -F 'file=@/tmp/写真照.png;type=image/png' http://httpbin.org/post
  1. {
  2. "args": {},
  3. "data": "",
  4. "files": {
  5. "file": "data:image/png;base64,*************上传的是图片,所以被 httpbin 转成 base64 了太长了省略掉吧,*************"
  6. },
  7. "form": {},
  8. "headers": {
  9. "Accept": "*/*",
  10. "Content-Length": "3007",
  11. "Content-Type": "multipart/form-data; boundary=----------------------------b9d70d880d9f",
  12. "Host": "httpbin.org",
  13. "User-Agent": "curl/7.29.0",
  14. "X-Amzn-Trace-Id": "Root=1-61193f5a-20d00ce725cfe8b94ccdc333"
  15. },
  16. "json": null,
  17. "origin": "220.191.56.11",
  18. "url": "http://httpbin.org/post"
  19. }

注意看第5 行, 识别出是 .png 文件了, 上面命令指定 MIME 类型为image/png,否则 curl 会把 MIME 类型设为application/octet-stream。

-F 参数也可以指定文件名。

$ curl -F ‘file=@photo.png;filename=me.png’ https://google.com/profile

  1. curl -F 'file=@/tmp/写真照.png;filename=xie_zhen.png' http://httpbin.org/post

上面命令中,原始文件名为 写真照.png,但是服务器接收到的文件名为 xie_zhen.png。

-G 参数用来构造 URL 的查询字符串。

  1. curl -G -d 'user=lwmacct' -d 'sid=123456789' http://httpbin.org/get
  1. {
  2. "args": {
  3. "sid": "123456789",
  4. "user": "lwmacct"
  5. },
  6. "headers": {
  7. "Accept": "*/*",
  8. "Host": "httpbin.org",
  9. "User-Agent": "curl/7.29.0",
  10. "X-Amzn-Trace-Id": "Root=1-611940fe-56d38ad22564a26252bb8360"
  11. },
  12. "origin": "220.191.56.11",
  13. "url": "http://httpbin.org/get?user=lwmacct&sid=123456789"
  14. }

上面命令会发出一个 GET 请求,实际请求的 URL 为 http://httpbin.org/get?user=lwmacct&sid=123456789
如果省略 -G,会发出一个 POST 请求。
如果数据需要 URL 编码,可以结合—data—urlencode参数。

-H参数添加 HTTP 请求的标头。

  1. curl -H 'Accept-Language: zh-CN' http://httpbin.org/get
  1. {
  2. "args": {},
  3. "headers": {
  4. "Accept": "*/*",
  5. "Accept-Language": "zh-CN",
  6. "Host": "httpbin.org",
  7. "User-Agent": "curl/7.29.0",
  8. "X-Amzn-Trace-Id": "Root=1-611941e0-5df5e25c49c111eb0776cd9b"
  9. },
  10. "origin": "220.191.56.11",
  11. "url": "http://httpbin.org/get"
  12. }

将信息头 Content-Type 改成 application/json 使得我curl 能发送 JSON 请求

  1. curl -H 'Content-Type: application/json;charset=utf-8' -H 'Secret-Message: login' -d '{"user":"lwmacct","password":"mima"}' http://httpbin.org/post
  1. {
  2. "args": {},
  3. "data": "{\"user\":\"lwmacct\",\"password\":\"mima\"}",
  4. "files": {},
  5. "form": {},
  6. "headers": {
  7. "Accept": "*/*",
  8. "Content-Length": "36",
  9. "Content-Type": "application/json;charset=utf-8",
  10. "Host": "httpbin.org",
  11. "Secret-Message": "login",
  12. "User-Agent": "curl/7.29.0",
  13. "X-Amzn-Trace-Id": "Root=1-6119434f-3060eec413548340251fc25a"
  14. },
  15. "json": {
  16. "password": "mima",
  17. "user": "lwmacct"
  18. },
  19. "origin": "220.191.56.11",
  20. "url": "http://httpbin.org/post"
  21. }

-i 参数打印出服务器回应的 HTTP 标头。

下面命令收到服务器回应后,先输出服务器回应的标头,然后空一行,再输出网页的源码

  1. curl -i http://httpbin.org/get
  1. HTTP/1.1 200 OK
  2. Date: Sun, 15 Aug 2021 16:51:17 GMT
  3. Content-Type: application/json
  4. Content-Length: 254
  5. Connection: keep-alive
  6. Server: gunicorn/19.9.0
  7. Access-Control-Allow-Origin: *
  8. Access-Control-Allow-Credentials: true
  9. {
  10. "args": {},
  11. "headers": {
  12. "Accept": "*/*",
  13. "Host": "httpbin.org",
  14. "User-Agent": "curl/7.29.0",
  15. "X-Amzn-Trace-Id": "Root=1-61194605-19fe8eaa11873cbe416ebbf8"
  16. },
  17. "origin": "220.191.56.11",
  18. "url": "http://httpbin.org/get"
  19. }

-I参数向服务器发出 HEAD 请求

将服务器返回的 HTTP 标头打印出来。
我们在学习 -c 的时候已经用过了 https://www.yuque.com/uuu/shell/curl#fxAgy
他认为他最大的作用就是可以用来,查看服务端返回的 cookie 文本和, 检查URL文件大小

  1. curl -I https://mirrors.aliyun.com/ubuntu/ls-lR.gz
  1. HTTP/1.1 200 OK
  2. Server: Tengine
  3. Content-Type: application/octet-stream
  4. Content-Length: 20918903
  5. Connection: keep-alive
  6. Date: Sun, 15 Aug 2021 16:44:45 GMT
  7. Last-Modified: Sun, 15 Aug 2021 12:10:53 GMT
  8. ETag: "6119044d-13f3277"
  9. Expires: Sun, 15 Aug 2021 16:49:45 GMT
  10. Cache-Control: max-age=300
  11. Via: cn1783.l1, cache20.cn1783, l2cn1833.l2, cache13.l2cn1833, samdb1.et2, cache13.l2cn1833[0,0,200-0,H], cache12.l2cn1833[0,0], vcache6.cn2038[1,0,200-0,M], vcache11.cn2038[2,0]
  12. Accept-Ranges: bytes
  13. Ali-Swift-Global-Savetime: 1629045885
  14. Age: 38
  15. X-Cache: MISS TCP_MISS dirn:-2:-2
  16. X-Swift-SaveTime: Sun, 15 Aug 2021 16:45:23 GMT
  17. X-Swift-CacheTime: 262
  18. Timing-Allow-Origin: *
  19. EagleId: 73eec09f16290459234304320e

—head 参数等同于-I。

  1. curl --head https://mirrors.aliyun.com/ubuntu/ls-lR.gz

-k参数指定跳过 SSL 检测。

  1. curl -k http://httpbin.org/get

上面命令不会检查服务器的 SSL 证书是否正确。

—cacert 指定 CA 证书位置

  1. curl --cacert [ca证书文件路径] [URL]

curl 指定客户端证书

  1. curl --cert [certificate_name] [url]

示例:

  1. curl --cert cert.pem https://www.example.com

如果证书是 pfx 格式, 而且有密码, 怎么办

  1. curl https://www.example.com -k --cert client.crt --key client.key

-L 参数会让 HTTP 请求跟随服务器的重定向

curl 默认不跟随重定向。

  1. curl -IL http://httpbin.org/cookies/set?admin=lwmacct\&auth=yuque

—limit-rate 限制回应带宽

  1. curl -o /tmp/curl.file.gz --limit-rate 100k https://mirrors.aliyun.com/ubuntu/ls-lR.gz

—limit-rate用来限制 HTTP 请求和回应的带宽,模拟慢网速的环境,

  1. [root@KuaiCDN ~]# curl -O --limit-rate 100k https://mirrors.aliyun.com/ubuntu/ls-lR.gz
  2. % Total % Received % Xferd Average Speed Time Time Time Current
  3. Dload Upload Total Spent Left Speed
  4. 5 19.9M 5 1199k 0 0 100k 0 0:03:22 0:00:11 0:03:11 104k

可以注意到我们在尝试下载一个文件时,速度被限制到了每秒 100K,

-o参数将服务器的回应保存成文件,等同于wget命令

  1. curl -o /tmp/curl.file.gz https://mirrors.aliyun.com/ubuntu/ls-lR.gz

使用 -o tar 命令 下载并解压

  1. mkdir /tmp/curl/tar_un/
  2. curl -o - https://mirrors.aliyun.com/zabbix/zabbix/5.4/ubuntu/pool/main/z/zabbix/zabbix_5.4.3-1%2Bubuntu14.04.debian.tar.gz | tar zxvf - -C /tmp/curl/tar_un/

-O 参数将服务器回应保存成文件,并将 URL 的最后部分当作文件名。

  1. curl -o /tmp/curl.file.gz https://mirrors.aliyun.com/ubuntu/ls-lR.gz

上面命令将服务器回应保存成文件,文件名为ls-lR.gz

-s 参数将不输出错误和进度信息。

  1. curl -s http://httpbin.org/get

上面命令一旦发生错误,不会显示错误信息。不发生错误的话,会正常显示运行结果。
如果想让 curl 不产生任何输出,可以使用下面的命令, 下面的命令适合搞事情

  1. curl -s -o /dev/null http://httpbin.org/get

-S 参数指定只输出错误信息,通常与-s一起使用。

$ curl -S -s -o /dev/null https://google.com

  1. curl -sS http://httpbin.org/get

上面命令没有任何输出,除非发生错误。

-u 参数用来设置服务器认证的用户名和密码。

  1. curl -u 'lwmacct:pwd' http://httpbin.org/basic-auth/lwmacct/pwd
  1. {
  2. "authenticated": true,
  3. "user": "lwmacct"
  4. }

上面命令设置用户名为 lwmacct,密码为 pwd,然后将其转为 HTTP 标头Authorization: Basic *

下面命令能够识别 URL 里面的用户名和密码,将其转为上个例子里面的 HTTP 标头。

  1. curl -i https://lwmacct:pwd@httpbin.org/basic-auth/lwmacct/pwd

你可以试试下面的命令,只设置了用户名,执行后,curl 会提示用户输入密码。

  1. curl -i -u lwmacct http://httpbin.org/basic-auth/lwmacct/pwd

-v 参数输出通信的整个过程,用于调试。

  1. curl -v http://httpbin.org/get


—trace 参数也可以用于调试,还会输出原始的二进制数据。

  1. curl --trace - http://httpbin.org/get

-x 参数指定 HTTP 请求的代理。

作者在网上花了十几分钟, 实在没找到免费的 socks5 代理, 花几秒钟,找了个搭建方法
Docker 运行 socks5 容器
以下容器镜像只能进行tcp代理, 如果想要udp代理, 那么请使用 ss5代理

  1. docker run -d -p 1080:1080 -e PROXY_USER=user -e PROXY_PASSWORD=password -e PROXY_SERVER=0.0.0.0:1080 xkuma/socks5

curl 使用 socks5 代理

  1. curl -x socks5://user:password@106.110.31.239:1080 http://httpbin.org/get
  1. {
  2. "args": {},
  3. "headers": {
  4. "Accept": "*/*",
  5. "Host": "httpbin.org",
  6. "User-Agent": "curl/7.29.0",
  7. "X-Amzn-Trace-Id": "Root=1-61195877-4751ad6f3c4380cc1ba0312d"
  8. },
  9. "origin": "106.110.31.239",
  10. "url": "http://httpbin.org/get"
  11. }

可以注意到, 识别到的IP 是代理IP
现在 来看看我们的真实IP是什么

  1. curl -4 ip.sb
  1. 220.191.56.111

更多关于代理的文档 请移步 https://www.yuque.com/uuu/proxy

-X 参数指定 HTTP 请求的方法。

  1. curl -X POST http://httpbin.org/post

上面命令对 http://httpbin.org/post 发出 POST 请求。


—interface 指定请求接口

  1. curl --interface eth0 -X GET https://www.yuque.com/uuu/linux/curl
  1. curl --interface 192.168.1.10 -X GET https://www.yuque.com/uuu/linux/curl