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 
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-typeContent-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
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

参考资料