<Curl 必知必会>读书
Contents
curl 项目
- Daniel Stenberg, 1996 发现 HttpGet (巴西人 Rafael Sagula). 接管并维护.
- 1997年 4 月 8 号 HttpGet 1.0 发布
- 1997年 8 月 urlget 2.0
- 1998 年 3 月 20 号 curl 4
- 2000 年 8 月 libcurl 7.1 发布
选项和参数
短选项
: 例如 -v
或 -L
或它们的组合 -vL
长选项
: 使用 --
两个减号, 后加选项名. 例如 --verbose
--location
选项的参数
: -k v
, 即中间用空格分隔. 如果使用了短选项方式, 则可不使用空格分隔
值包含空格, 则要用双引号
来引用.(大多情况下建议, 有些系统也可用单引号)
负选项
: --no-
前缀. 例如关闭详细模式, --no-verbose
-K
或--config
: 通过文件或标准输入来提供命令行选项.(即配置文件).- 查找主目录.
CURL_HOME
环境变量, 如果没有则是HOME
环境变量. - 默认情况下, 它会从
主目录
找~/.curlrc
文件中读取. - 以
#
开头的表示是注释 - 每一行表示一个参数
- 如果是
-K -
表示从 stdin 读入.
- 查找主目录.
-v
: 详细输出--proto-default
: 修改默认协议(默认为 HTTP)--fail-early
处理多个 URL 时快速失败. 默认 curl 会处理完最后一个 URL 后返回一个退出码. 这个参数表示第一次出现错误就立即退出. 多 URL 请看下面的部分.-s
或--silent
: 关闭进度指示器- 保存文件名相关(注意, curl 下载并不会对数据进行任何转换, 字符问题可用
iconv
来转换)-o
: 指定下载保存的文件名. (字母小写 o)-O
: 使用 URL 最后的路径名作为保存的文件名. (字母大写 O)-J
或--remote-header-name
: 使用 HTPP 响应头的Content-Disposition
建议的文件名来作为保存名(要注意小心被覆盖或字符集问题)
--compressed
: 建议服务器压缩来传输.
多个 URL
curl 支持无限数量的 URL . 只要你的 shell 系统支持. 如果有非常多的URL 的话. 可以这样子用
xargs curl < /tmp/urls
注意, 指定多个 URL , 它是按顺序一个一个处理. 前一个没处理完, 是不是处理下一个 URL
多个 URL 与下载
# 注意单个 -o 或 -O , 只用于单个下载. 如果要下载多个 URL , 则需要使用多个 -o 或 -O
# 例如
curl -O -O http://hello.com/1.txt http://hello.com/2.txt
# 更为方便的用法. 以下表示所有都使用 -O 选项作为默认
curl --remote-name-all http://hello.com/1.txt http://hello.com/2.txt
URL 的单独选项
curl -L www.qq.com --next -X GET www.qq.com --next -I www.qq.com
--next
或 -;
用于在一组选项和 URL 之间插入间隔. 遇到 --next
时, 它会将后面的选项应用到下一组 URL .
用户名和密码
curl -u name:passwd http://www.fuck.com
可以指定 u 而没带参数值, 则会自动提示叫你输入
进度指示器
默认开启. 可以通过 -s
或 --silent
禁用.
例子
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 21946 100 21946 0 0 157k 0 --:--:-- --:--:-- --:--:-- 158k
从左到右:
%
: 整个传输百分比Total
: 整个传输的总大小%
: 已完成的下载百分比Received
: 已下载字节数%
: 已完成的上传百分比Xferd
: 已上传字节数Average Speed Dload
: 整个下载的平均速度. 单位byte/s
Average Speed Upload
: 整个上传的平均速度. 单位byte/s
Time Total
: 预期完成操作时间.HH:MM:ss
Time Current
: 从传输开始到现在的时间.HH:MM:ss
Time Left
: 预期完成操作所需要的剩余时间.HH:MM:ss
Curr.Speed
: 过去 5 秒的平均传输速度.byte/s
连接重用
在运行期间的 curl 内部会维护一个连接池. 所以, 最好在同一个命令中完成多次传输, 而不是单独运行多个 curl 命令
* Connected to www.qq.com (113.96.232.215) port 80 (#0)
(#0)
这个就是 curl 为这个连接分配的内部数字.
但只要 curl 退出后, 它就会关闭所有已打开的连接和连接池的连接
通配
默认 curl 使用 []
和 {}
进行通配. 可以通过 -g
或 --globoff
禁用它.
范围 []
curl -O http://example.com/[1-100].png
# 零前缀
curl -O http://example.com/[001-100].png
# 步进
curl -O http://example.com/[0-100:2].png
列表 {}
curl -O http://example.com/{one,two,three,alpha,beta}.html
# 组合
curl -O http://example.com/{Ben,Alice,Frank}-{100x100,1000x1000}.jpg
组合
curl -O http://example.com/{web,mail}-log[0-6].txt
输出
可以在输出时引用通配变量
curl http://{one,two}.example.com -o "file_#1.txt"
curl http://{site,host}.host[1-5].example.com -o "subdir/#1_#2"
详细模式
-v
--trace [filename]
将完整的跟踪信息保存在指定文件. (包括实际传输数据在内的完整消息)--trace-ascii [filename]
: 同上, 但输出的是 ASCII 字符, 而不是十六进制数字--trace-time
: 加上高精度时间curl --trace /tmp/curl.tarce http://www.qq.com # 或输出到控制台: curl --trace - http://www.qq.com
--write-out
或 -w
它可在传输任务完成后打印一些信息.
- 字符串
-w "hello"
- 从文件读取
-w @/path/to/filename
- 从标准输入读取
-w @-
- 可在字符串中使用
%{var_name}
来访问可用变量.
可用的变量有
%{content_type}
: 显示ContentType
%{filename_effective}
: 显示 curl 最终写入内容的文件名. 只有使用--remote-name
或--output
选项写入文件才有意义. 与--remote-header-name
选项结合最有用.%{ftp_entry_path}
: 显示连接到远程 FTP 服务器时的初始路径%{response_code}
: 显示最后一次传输返回的响应码%{http_connect}
: 显示最近一次会对 CONNECT 请求的响应码(来自代理)%{local_ip}
: 显示最近一次连接的本地 IP 地址%{local_port}
: 显示最近一次连接的端口号%{num_connects}
: 显示最近一次传输建立的新连接的数量%{num_redirects}
: 显示请求的重定向次数%{redirect_url}
: 显示不使用-L
时的重定向 URL%{remote_ip}
: 显示最近一次连接的远程 IP 地址%{remote_port}
: 显示最近一次连接的远程端口%{size_download}
: 显示已下载的总字节数%{size_header}
: 显示已下载 header 的总字节数%{size_request}
: 显示 HTTP 请求发送的总字节数%{size_upload}
: 已上传的总字节数%{speed_download}
: 显示整个下载的平均速率.byte/s
%{speed_upload}
: 显示整个上传的平均速率%{ssl_verify_result}
: 显示 SSL 验证结果。 0 表示成功.%{time_appconnect}
: 从开始到远程主机建立 SSL 或 SSH 连接所花费的时间。 以秒为单位%{time_connect}
: 显示从开始到远程主机建立 TCP 所花费的时间。 以秒为单位%{time_namelookup}
: 显示从开始到完成解析域名所花的时间。以秒为单位%{time_pretransfer}
: 显示从开始到文件传输即将开始所花的时间。 包括用于所有预传输命令以及特定协议协商的时间, 以秒为单位。%{time_redirect}
: 显示重定向所花的时间, 包括在最终事务启动之前的域名查找, 建立连接, 预传输和传输。 以秒为单位%{time_starttransfer}
: 从开始到第一个字节即将开始传输所花的时间。 包括time_pretransfer
以及服务器计算结果所需要的时间, 以秒为单位。%{time_total}
: 显示整个操作持续的时间。 以秒为单位。%{url_effective}
: 显示最后获取的 URL。 如果你要 curl 跟随重定向(-L
), 那这人变量就非常有用
静默模式
-s
或 --silent
, 不会在发生错误时输出任何错误信息。 但仍会处理。
可添加 -S
或 --show-error
来显示有错误时显示错误信息
下载
速率
curl http://qq.com --limit-rate 200[K|M|G]
大小
# 单位字节
curl http://qq.com --max-filesize 100000
metalink
curl --metalink https://hello.com/example.metalink
原始 --raw
这个选项会禁用所有内部的 HTTP 内容解码或传输编码.比如开发中间件时就很有用
.
失败重试
--retry
: 设置重试次数. 默认为 0 即不重试.--retry-delay
: 禁用指数退避算法, 并设置自己的重试延迟. 默认重试等待时间为延时 1 秒, 2 秒, 4 秒
这种指数加倍.--retry-max-time
: 限制所有重试的总时间--max-time
: 用于指定单个传输允许的最长时间--connect-timeout
: 连接超时.--connect-timeout 2.71
表示 2710 毫秒
恢复下载和下载范围
-C
或--continu-at
: 指定从某个数字字节偏移量开始. 用-
的话, 表示让 curl 自动决定.--range X-Y
: 表示只从某范围下载数据
上传
POST 上传
Multipart formpost 上传
PUT 上传
curl -T uploadthis http://example.com/
FTP上传
curl -T uploadthis ftp://example.com/dir/
curl -T uploadthis ftp://example.com/dir/newName
速度
参考 --limit-rate
主机解析
hosts 文件
127.0.0.1 example.com
Host Header
curl -H "Host: www.example.com" http://localhost/
自定义 IP
curl --resolve example.com:80:127.0.0.1 http://example.com/
提供替换名
curl --connect-to www.example.com:80:newName.example.com:80 http://www.example.com
它将 www.example.co:80
重定向到 newName.examp
连接相关
--connect-timeout
: 连接超时--max-time
或-m
: 总用时--interface
: 使用指定本地网卡或 IP--interface eth1
--interface 192.168.1.10
--local-port 4200~4205
: 使用指定本地端口范围来进行连接
keepalive
默认情况下, curl 启用 tcp keepalive.
--no-keepalive
表示禁用 tcp keepalive--keepalive-time 300
: keepalive 发送心跳的间隔, 单位秒
速率控制及退出
curl --speed-time 15 --speed-limit 1000 http://example.com
表示在 15 秒
内的传输速率低于 1000 byte/s
, 则停止.
代理
# 小写字母 x, 表示通过代理服务器 192.168.0.1:8080 来访问 exapmle.com
curl -x 192.168.0.1:8080 http://example.com
curl -x 192.168.0.1:8080 https://example.com
代理环境变量
http_proxy=http://proxy.example.com:80
ftp_proxy=xxx
# https 协议时使用这个代理
https_proxy=yyyy
# 所有协议都使用这个代理
ALL_PROXY=NNNN
# 指定某些 host 不需要通过代理
NO_PROXY=www.example.com,www.no-proxy.com
curl -v www.example.com
HTTP 操作
方法
- 默认为
GET
-d
或-F
为 POST-I
为 HEAD-T
为 PUT
认证
curl --user name:pwd http://hello.com/
# 自动使用最安全的方法
curl --anyauth --user name:pwd http://hello.com/
# 指定方法
curl --digest --user daniel:secret http://example.com/
curl --negotiate --user daniel:secret http://example.com/
curl --ntlm --user daniel:secret http://example.com/
区间
curl -r 0-199 http://example.com
curl -r 200- http://example.com
curl -r 0-199,1000-199 http://example.com/
HTTP 版本
--http1.0
--http1.1
--http2
--http2-prior-knowledge
--http3
POST
curl -d 'name=admin&shoesize=12' http://example.com/
# curl 自动会将它们串连起来, 并插入 & 字符
curl -d name=admin -d shoesize=12 http://example.com/
# 文件
curl -d @filename http://example.com
Content-Type
默认使用 -d
时的 content-type
为 Content-Type: application/x-www-form-urlencoded
指定为 JSON
curl -d '{json}' -H 'Content-Type: application/json' https://example.com
二进制内容
curl --data-binary @filename http://example.com/
如果使用 -d
的话, 回车符和换行符会被移除. 但使用 --data-binary
则表示原始数据
URL encode
# 编码后为 name=John%20Doe%20%28Junior%29
curl --data-urlencode "name=John Doe (Junior)" http://example.com
# 如果内容保存在文件. 表示使用 user 作为参数名. contents.txt 的内容作为值并编码
curl --data-urlencode user@contents.txt http://example.com
# 如果 name 也想编码. 表示参数名为 `user name`, 前面的等号并不会发送
curl --data-urlencode "=user name=John Doe (Junior)" http://example.com
转换为 GET
使用 -G
或 --get
选项, 它将 -d
指定的数据附加到 URL 右边, 并使用 ?
分隔.
发送表单 form
通过 -F
或 --form
选项添加单独的 multipart
.
curl -F person=anonymous -F secret=@file.txt http://example.com/submit.cgi
请求头
# 添加
curl -H "name: value" http://example.com/
# 删除. name 后分号
curl -H "name;" http://example.com/
referer
curl --referer http://comes-from.example.com https://www.example.com/
ua
curl -A "new agent" http://example.com
curl --user-agent http://example.com
curl -H "User-Agent: new agent" http://example.com
cookie
# 从指定文件中读取 cookie
curl -L -b cookies.txt http://example.com
# 保存 cookie 到文件
curl -c cookie-jar.txt http://example.com
# 新 cookie 会话
curl -j -b cookies.txt http://example.com/
http2
curl --http2 http://example.com/
使用例子
诊断
将以下保存到 curl.debug
文件, 然后 curl -v -w @curl.debug -s http://www.qq.com
\n\n
content_type: %{content_type}\n
filename_effective: %{filename_effective}\n
ftp_entry_path: %{ftp_entry_path}\n
http_code: %{http_code}\n
http_connect: %{http_connect}\n
local_ip: %{local_ip}\n
local_port: %{local_port}\n
num_connects: %{num_connects}\n
num_redirects: %{num_redirects}\n
redirect_url: %{redirect_url}\n
remote_ip: %{remote_ip}\n
remote_port: %{remote_port}\n
size_download: %{size_download}\n
size_header: %{size_header}\n
size_request: %{size_request}\n
size_upload: %{size_upload}\n
speed_download: %{speed_download}\n
speed_upload: %{speed_upload}\n
ssl_verify_result: %{ssl_verify_result}\n
url_effective: %{url_effective}\n
\n\n
time_namelookup: %{time_namelookup}\n
time_connect: %{time_connect}\n
time_appconnect: %{time_appconnect}\n
time_pretransfer: %{time_pretransfer}\n
time_redirect: %{time_redirect}\n
time_starttransfer: %{time_starttransfer}\n
-------\n
time_total: %{time_total}\n
\n