<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/sAverage Speed Upload: 整个上传的平均速度. 单位byte/sTime Total: 预期完成操作时间.HH:MM:ssTime Current: 从传输开始到现在的时间.HH:MM:ssTime Left: 预期完成操作所需要的剩余时间.HH:MM:ssCurr.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