「CURL」- 访问地址以传输或拉取数据

内容: 介绍 cURL Version 7.50

认识

curl 是一个命令行工具,用于从服务器获取数据或者向服务器发送数据。命令 curl 是一个用于从服务器拉取或发送数据的工具。使用以下支持的协议之一:DICT,FILE,FTP,FTPS,GOPHER,HTTP,HTTPS,IMAP,IMAPS,LDAP,LDAPS,POP3,POP3S,RTMP,RTSP,SCP,SFTP,SMB,SMBS,SMTP,SMTPS,TELNET,TFTP。该命令旨在无需用户交互即可工作。

命令 curl 提供了大量有用的技巧,如代理支持、用户身份验证、FTP 上传、HTTP 的 POST 请求、SSL 连接、cookie、文件传输恢复、Metalink 等等。正如本文下面解释的,功能多到让人头晕目眩!

curl 提供了一大堆功能,比如支持代理、用户认证、FTP 上传、HTTP POST、SSL 链接、cookie、Metalink、文件传输恢复等。正如手册所说: As you will see below, the number of features will make your head spin!

官网:https://curl.haxx.se
文档:https://curl.haxx.se/docs/manpage.html
仓库:https://github.com/curl/curl

组成

curl 依赖于 libcurl 库,”man 3 libcurl“查看 libcurl 的详细信息。命令 curl 中所有与传输相关的功能都由 libcurl 为提供支持。有关详细信息,请参阅 libcurl(3)。

构造

CentOS Linux release 7.9.2009 (Core)

安装最新版本:

# vim /etc/yum.repos.d/city-fan.repo
[CityFan]
name=City Fan Repo
baseurl=http://www.city-fan.org/ftp/contrib/yum-repo/rhel$releasever/$basearch/
enabled=1
gpgcheck=0

# yum clean all
# yum install curl

安装的可执行程序

curl | is a command line tool for transferring files with URL syntax.

curl-config,获取 libcurl 的安装信息,命令 curl-config 显示有关 curl 和 libcurl 安装的信息。
prints information about the last compile, like libraries linked to and prefix setting.

性质

文件下载:

curl http://example.com/folder/big-file.iso -O
curl http://example.com/folder/big-file.iso -o myfile.txt

如果请求失败,则退出:

curl -s --fail https://httpbin.org/status/401
curl -s --fail-with-body https://httpbin.org/status/401

// 注意事项,
// 1)这仅能处理 400 及以上的相应码;
// 2)其他状态码,比如 301 状态,需要自行脚本实现;

跟随重定向,并返回最终地址:

curl -Ls -o /dev/null -w %{url_effective} http://google.com

测试端口开放:

curl -v telnet://127.0.0.1:22

指定请求头,这里我们指定 Host 头部:

curl --header "Host: example.com" http://127.0.0.1/
curl -H "Host: example.com" http://127.0.0.1/

# 注意事项:
# 1)该方法不适用于 HTTPS 协议

请求 Unix Socket 文件:

curl --unix-socket /var/run/docker.sock \
   "http://localhost-or-dummy/containers/<id>/stats?stream=false"

访问某个集群,只返回请求头,以检查是否存在异常响应:

for i in $(seq 111 126)
do
    ip_address="192.168.50.$i"
    echo "####### IP ADDRESS:" $ip_address
    curl -s --head \
        --resolve "www.example.com:443:$ip_address" \
        'https://www.example.com/path/to/somewhere?a=b'
done

自定义输出

输出状态码(stdout – Can I make cURL fail with an exitCode different than 0 if the HTTP status code is not 200?):

curl --silent --output /dev/null --write-out "%{http_code}"

输出响应时间:

# 第一步、定义 example.txt 文件:
     time_namelookup:  %{time_namelookup}s\n
       time_connect:  %{time_connect}s\n
    time_appconnect:  %{time_appconnect}s\n
   time_pretransfer:  %{time_pretransfer}s\n
      time_redirect:  %{time_redirect}s\n
 time_starttransfer:  %{time_starttransfer}s\n
                    ----------\n
         time_total:  %{time_total}s\n

# 第二步、使用该配置文件
curl -w "@curl-format.txt" -o /dev/null -s "http://wordpress.com/"

语法格式

curl [options] [URL...]

控制输出信息

-v, –verbose
在操作过程中,使 curl 输出更多信息。用于调试和查看“引擎盖下”发生了什么。以“>”开头的行表示由 curl 发送的“头数据”;“<”开始的行表示在正常情况下隐藏的 curl 接收的“头数据”;以“*”开头的行表示 curl 提供的其他信息。

如果您只想在输出中包含 HTTP 头,则可以使用-i(–include)选项,此选项会覆盖–trace 和–trace-ascii 选项。

如果您认为此选项仍未提供足够的详细信息,请考虑使用–trace 或–trace-ascii 选项。

使用-s(–silent)使 curl 出于安静模式,不显示信息。

-i, –include
在输出中包含 HTTP 头。HTTP 头包括服务器名、文档日期、HTTP 版本等等更多信息。

参见-v(–verbose)选项。

-s, –silent
安静模式。不显示进度条或者错误消息。它仍会输出您要求的数据,甚至可能输出到终端 / 标准输出,除非您重定向它。

参见-v(–verbose)和–stderr 选项。

–stderr
将所有写入标准错误的数据重定向到指定的文件。如果文件名是普通的’-‘,则将其写入标准输出。如果多次使用此选项,将使用最后一个选项。

参见-v(–verbose)和-s(–silent)选项。

–trace <file>
启用完整跟踪转储,对所有传入和传出数据(包括描述性信息)写入给定的输出文件中。使用“-”作为文件名,则将输出发送到标准输出;使用“%”作为文件名,则将输出发送到标准错误。

如果多次使用此选项,将使用最后一个选项。

此选项会覆盖-v(–verbose)和–trace-ascii。

–trace-ascii <file>
启用完整跟踪转储,对所有传入和传出数据(包括描述性信息)写入给定的输出文件中。使用“-”作为文件名,则将输出发送到标准输出;使用“%”作为文件名,则将输出发送到标准错误。

这与–trace 非常相似,但是输出中不包括十六进制部分,只显示转储的 ASCII 部分。它产生较小的输出,并更容易阅读。

如果多次使用此选项,将使用最后一个选项。

此选项会覆盖–trace 和-v(–verbose)。

-h, –help
用法帮助。列出当前所有命令行选项以及简短描述。

代理协议前缀

Since curl version 7.21.7, the proxy string may be specified with a protocol:// prefix to specify alternative proxy protocols.

If no protocol is specified in the proxy string or if the string doesn’t match a supported one, the proxy will be treated as an HTTP proxy.

The supported proxy protocol prefixes are as follows:

socks4://
Makes it the equivalent of –socks4

socks4a://
Makes it the equivalent of –socks4a

socks5://
Makes it the equivalent of –socks5

socks5h://
Makes it the equivalent of –socks5-hostname

进度条

curl normally displays a progress meter during operations, indicating the amount of transferred data, transfer speeds and estimated

time left, etc. The progress meter displays number of bytes and the speeds are in bytes per second. The suffixes (k, M, G, T, P) are

1024 based. For example 1k is 1024 bytes. 1M is 1048576 bytes.

curl displays this data to the terminal by default, so if you invoke curl to do an operation and it is about to write data to the ter‐

minal, it disables the progress meter as otherwise it would mess up the output mixing progress meter and response data.

If you want a progress meter for HTTP POST or PUT requests, you need to redirect the response output to a file, using shell redirect

(>), -o [file] or similar.

It is not the same case for FTP upload as that operation does not spit out any response data to the terminal.

If you prefer a progress “bar” instead of the regular meter, -#, –progress-bar is your friend.

相关文件

~/.curlrc
Default config file, see -K, –config for details.

相关环境变量

The environment variables can be specified in lower case or upper case. The lower case version has precedence. http_proxy is an exception as it is only available in lower case.

Using an environment variable to set the proxy has the same effect as using the -x, –proxy option.

http_proxy [protocol://]<host>[:port]
Sets the proxy server to use for HTTP.

HTTPS_PROXY [protocol://]<host>[:port]
Sets the proxy server to use for HTTPS.

[url-protocol]_PROXY [protocol://]<host>[:port]
Sets the proxy server to use for [url-protocol], where the protocol is a protocol that curl supports and as specified in a URL. FTP, FTPS, POP3, IMAP, SMTP, LDAP etc.

ALL_PROXY [protocol://]<host>[:port]
Sets the proxy server to use if no protocol-specific proxy is set.

NO_PROXY <comma-separated list of hosts>
list of host names that shouldn’t go through any proxy. If set to a asterisk ‘*’ only, it matches all hosts.

curl 命令支持的选项。

-H, –header <header>
格式:-H ‘Accept-Language: en-US,en;q=0.5’
适用协议:HTTP
用于发送请求头到服务器。支持任意数量的头信息,即可以使用多个-H 选项来添加、删除、替换头信息。
注意:如果指定的”头名“和 cURL 内置的头名相同,则”头值“会覆盖 cURL 默认的头值。如果你不知道你做什么,那就不要替换默认的”头值“。
如果要删除内置的头信息,只需要指定一个空”头值“,如:-H “Host:”。
但是如果你要发送一个没有值的头,需要附加一个分号(;),如:要发送”X-Custom-Header:”,使用-H “X-Custom-Header;”
-A, –user-agent, -e, –referer 这几个选项也和头信息有关。

#!/bin/bash
# 示例:
curl -H "X-First-Name: Joe" http://example.com/

# 注意事项:
#	1). 每一条头信息结束之后都有一个换行符,cURL 会自动为你添加,不需要手动添加换行符。
#	2). 从 7.37.0 开始,要使用--proxy-header 选项发送自定义的代理头。
# 	3). -H 选项指定的头信息会应用到所有的请求中,与-L 选项一起使用时要注意,这可能会导致头信息发送到其他的主机。
#		所以有重定向(-L)的情况下,需要小心使用包含敏感的头部。

-o, –output <file>
将输出内容写入<file>中,来代替默认的 stdout。如果<file>为-,也会输出到 stdout。
如果使用{}或者[]来获取多个文档,那么可以在<file>中使用“#后跟数字”形式的变量,变量会被替换成当前正在获取的 URL 中的字符串。如下示例:

curl http://{one,two}.example.com -o “file_#1.txt”

或者使用多个参数:

curl http://{site,host}.host[1-5].com -o “#1_#2”

此选项可以使用与网址数量一样多的次数。

查看用于动态创建文件夹就得–create-dirs选项。

HTTP 请求发送数据

-d, –data <data>

适用协议:HTTP

用于在 POST 请求中指出要发送数据(类似浏览器中 form 表单数据提交)。这将导致 curl 使用content-type application/x-www-form-urlencoded将数据传递到服务器(对比-F, –form)。

–data-ascii 与-d, –data 是相同的。

–data-raw 几乎是一样的,但–data-raw 没有对@字符的特殊解释。

–data-binary 用于发送二进制数据。

–data-urlencode 对 URL 表示字段的值进行 URL 编码。

如果多次使用这些选项,则数据最终会使用&符拼接起来。比如,使用’-d name=daniel -d skill=lousy’将生成一个看起来像’name=daniel&skill=lousy’的后置块。

当<data>以@开始,那么剩余部分应该是一个文件名(包含要发送数据)或(curl 从 stdin 读取数据)。也可以指定多个文件。因此,要发送 foobar 文件中的数据应该使用 --data @foobar。当–data 从文件中读取要发送数据时,回车符和换行符将被删除。如果你不希望使用@字符进行特殊解释,则使用–data-raw。

–data-binary <data>

适用协议:HTTP

(HTTP) This posts data exactly as specified with no extra processing whatsoever.

If you start the data with the letter @, the rest should be a filename. Data is posted in a similar manner as –data-ascii does, except that newlines and carriage returns are preserved and conversions are never done.

If this option is used several times, the ones following the first will append data as described in -d, –data.

应用

场景 | HTTP Request | POST, GET, …

curl POST examples
bash – How to urlencode data for curl command? – Stack Overflow
http – How do I make a POST request using curl? – Super User

curl --data "param1=value1&param2=value2" https://example.com/
curl --data "param1=value1" --data "param2=value2" https://example.com

curl --data-urlencode "paramName=value" --data-urlencode "secondParam=value" https://example.com

curl -d '{"key1":"value1", "key2":"value2"}' -H "Content-Type: application/json" -X POST http://localhost:3000/data

curl -d "@data.json" -X POST http://localhost:3000/data     # 或,将使用文件中的 JSON 数据

场景 | 指定域名的 DNS 解析

curl – How to test a HTTPS URL with a given IP address – Server Fault

curl https://DOMAIN.EXAMPLE –resolve ‘DOMAIN.EXAMPLE:443:192.0.2.17’

改进

Failed writing body

Why CURL return and error (23) Failed writing body?

处理(23) Failed writing body错误。

问题描述

执行curl “url” | grep -qs foo命令时,产生(23) Failed writing body错误。

问题原因

上述错误是由于管道过早关闭产生的。

当crul数据还没有写完,而后面的grep命令已经将管道关闭。类似的命令还有很多,某些程序在得到期望中的数据后,会立即关闭管道,而导致前面的程序写入失败。

解决办法

如果该错误无关紧要可以忽略它,通过重定向或者选项来抑制错误。

如果想要处理这个错误,可以使用tac命令:curl “url” | tac | tac | grep -qs foo

参考

man 1 curl, Version 7.52.1-4
CURL ANOTHER HOST
How do I measure request and response times at once using cURL?
Can cURL send requests to sockets? – Super User
How to capture cURL output to a file? – Stack Overflow
stdout – Can I make cURL fail with an exitCode different than 0 if the HTTP status code is not 200?
Test TCP connectivity with curl
linux – Get final URL after curl is redirected – Stack Overflow
How to send a header using a HTTP request through a cURL call? – Stack Overflow
Wiki: https://en.wikipedia.org/wiki/CURL
yum – Upgrade cURL to latest on CentOS – Server Fault