2025年2月24日 星期一 甲辰(龙)年 腊月廿四 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 软件应用 > 网络应用

10 个例子展示为什么 cURL 是一个很棒的命令行工具

时间:11-23来源:作者:点击数:17
城东书院 www.cdsy.xyz

无论你是开发者、DevOps 工程师、系统管理员、QA 还是其他技术岗位,你一定对 cURL 很熟悉——用于通过 URL 传输数据的命令行工具和库。

然而,大多数时候,我们都只用 curl 来做一些简单的任务,比如下载文件或检查网站是否可访问,但 curl 能做的远不止这些!

在这篇文章中,我们将介绍一些很酷的例子和技巧,展示为什么 curl 是一个非常棒且被低估的工具……

文件名代换

首先介绍的是文件名代换,它允许我们用一个 curl 命令发出多个请求:

  • $ curl -s "https://jsonplaceholder.typicode.com/users/[1-3]" | jq -s .
  • $ curl -s "https://jsonplaceholder.typicode.com/users/[0-10:2]" | jq -s .
  • $ curl -s "https://jsonplaceholder.typicode.com/photos/{1,6,35}" | jq -s .
  • $ curl -s "https://jsonplaceholder.typicode.com/users/[1-3]" -o "file_#1.json"

前两个命令展示了如何运行一系列请求——第一个命令会产生对 .../users/1.../users/2 和 .../users/3 的请求,而另一个使用步长选项,产生 2、4、6、8 和 10 的请求。考虑到这些特定请求返回的是 JSON,我们还将它与 jq ... 和 -s(slurp)操作符结合,将单个请求的响应合并为一个数组。

第三个例子使用了特定数字的列表而不是范围,这也适用于字符和单词。例如,我们可以使用 globbing 发出带有多种协议的请求:{http,https}://...

最后一个例子将 globbing 与输出变量结合,文件名中的 #1 变量指的是范围 [1-3]。这将生成 file_1.jsonfile_2.json 和 file_3.json

配置文件

大多数时候,使用 curl 时我们可能希望传递相同的命令行选项,如代理设置、请求超时、头信息等。这时名为 .curlrc 的 curl 配置文件可能会派上用场:

  • # ~/.curlrc
  • # 一些头信息
  • -H "Upgrade-Insecure-Requests: 1"
  • -H "Accept-Language: en-US,en;q=0.8"
  • # 跟随重定向
  • --location

这只是一个文本文件,每行代表一个将传递给 curl 的选项。它会自动从 ~/.curlrc 读取,所以你不需要任何额外的标志,但你可以使用 -K 来覆盖或指定不同的位置,例如:

  • $ curl -K .curlrc https://google.com

类似于标志和选项,有时我们也希望传递凭据。这可以通过 --user 选项来完成,但这会将凭据留在 Shell 历史记录中,所以我们可以利用 curl 支持的 .netrc 文件:

  • # ~/.netrc
  • machine https://authenticationtest.com/HTTPAuth/
  • login user
  • password pass

格式包括 machine(URL)、login 和 password。它们可以在一行中或如上所示,并且我们可以在一个文件中有多个。要使用它,只需将其传递给 curl

  • $ curl --netrc-file .netrc https://authenticationtest.com/HTTPAuth/

并行请求

我们已经在 文件名代换部分 讨论了请求的范围,但并行化呢?好吧,curl 也能做到:

  • $ curl -I --parallel --parallel-immediate --parallel-max 3 --config websites.txt
  • $ curl -I --parallel --parallel-immediate --parallel-max 3 stackoverflow.com google.com example.com

我们需要做的只是添加 --parallel(或 -Z),curl 将打开最多 50 个并行连接(可以通过 --parallel-max N 更改)。

还要注意我们是如何提供 URL 的,第一种方法是通过 --config 参数和一个文本文件,看起来像这样:

  • url = "stackoverflow.com"
  • url = "google.com"
  • url = "example.com"

另一个方法是将所有 URL 放在命令行上。这两个选项也适用于非并行请求!

格式化和变量

curl 可以输出很多东西,有时会让人不知所措、冗长且不必要。幸运的是,我们可以使用输出格式化只打印我们感兴趣的内容:

  • $ curl --silent --output /dev/null --show-error -w @format.txt http://example.com/
  • # 类型: text/html; charset=UTF-8
  • # 代码: 200
  • #
  • # 从 8.1.0:
  • # 协议: http
  • # 主机: example.com
  • # 端口: 80
  • #
  • # 读取头信息内容 (v7.83.0):
  • # 服务器: Sat, 29 Jun 2024 13:01:30 GMT

我们通过使用 -w 选项并传递一个格式文件来实现这一点。要生成上述输出,可以使用:

  • # format.txt
  • 类型: %{content_type}\n代码: %{response_code}\n\n
  • 8.1.0:\n\n
  • 协议: %{url.scheme}\n
  • 主机: %{url.host}\n
  • 端口: %{url.port}\n
  • 读取头信息内容 (v7.83.0):\n
  • %header{date}

每个变量都用 %{...} 包围。它们可以是简单变量,如 response_code,也可以是 url.<NAME> 的一部分,指的是 URL 组件,如主机或端口。最后,我们还可以使用 %header{HEADER_NAME} 变量输出响应头信息。

格式化的一个很好的用途是测量请求/响应时间,可以用以下格式来实现:

  • # format.txt
  • 域名解析时间: %{time_namelookup}s\n
  • 连接时间: %{time_connect}s\n
  • 应用连接时间: %{time_appconnect}s\n
  • 预传输时间: %{time_pretransfer}s\n
  • 重定向时间: %{time_redirect}s\n
  • 开始传输时间: %{time_starttransfer}s\n
  • ----------\n
  • 总时间: %{time_total}s\n
  • # 输出:
  • 域名解析时间: 0.000765s
  • 连接时间: 0.111908s
  • 应用连接时间: 0.000000s
  • 预传输时间: 0.111967s
  • 重定向时间: 0.000000s
  • 开始传输时间: 0.223373s
  • ----------
  • 总时间: 0.223992s

有关完整的变量列表,请参阅 文档

测试与故障排除

使用 curl 最常见的方式是进行(网络)故障排除。通常只需对特定 URL 发出请求即可提供足够的信息,但我们可以做更多的事情,例如我们可以强制使用特定的本地网络接口:

  • $ ip link show
  • # ...
  • # 3: wlp5s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000
  • $ curl --interface wlp5s0 https://example.com

同样,我们可以强制使用特定的 DNS 服务器:

  • $ curl --dns-ipv4-addr 1.1.1.1 https://example.com

或者我们可以测试超时并捕获退出代码(退出代码):

  • curl --connect-timeout 30 --silent --output /dev/null \
  • --show-error -w '总时间: %{time_total}s\n' http://google.com/ || EXIT_CODE=$?
  • if [ $EXIT_CODE = 28 ]
  • then
  • echo "无法连接(超时)。"
  • else
  • echo "可以连接。"
  • fi

这对测试代理服务器是否正常工作非常有用(使用 -x http://proxy.example.com:80)。

Trurl

curl 不只是一个 CLI 工具——该项目还包括 libcurl 以及 trurl,我想在这里展示一下。

trurl 是一个用于解析 URL 的专用工具,是 curl 的兄弟项目。可以从源代码安装:

  • $ sudo apt-get install libcurl4-openssl-dev
  • $ git clone https://github.com/curl/trurl.git
  • $ cd trurl
  • $ make
  • # ...

这里有几个使用它的例子:

  • $ trurl --url https://example.com/some/path/to/file.html --get '{path}'
  • # /some/path/to/file.html
  • $ trurl --url "https://example.com/?name=hello" --append query=key=value
  • # https://example.com/?name=hello&key=value
  • # 解析为 JSON:
  • $ trurl --url "https://example.com/?name=hello" --json
  • # [
  • # {
  • # "url": "https://example.com/?name=hello",
  • # "parts": {
  • # "scheme": "https",
  • # "host": "example.com",
  • # "path": "/",
  • # "query": "name=hello"
  • # },
  • # "params": [
  • # {
  • # "key": "name",
  • # "value": "hello"
  • # }
  • # ]
  • # }
  • # ]

第一个例子展示了如何提取 URL 组件,这里是路径,但也可以是如 url、scheme、user、password、options 或 host 等。

第二个例子使用 append 功能,向 URL 添加查询参数。

最后一个例子展示了 --json 选项,它将解析的 URL 输出为 JSON,非常适合进一步处理。

trurl 可以做更多事情,你可以查看 这个视频 或 手册(底部有例子)。

发送/上传数据

大多数时候我们使用 curl 下载或请求数据,但它(显然)也可以发送数据。用 curl 发送 POST 数据并不是什么新鲜事,对吧?

  • $ curl -X POST "https://httpbin.org/post" -H "accept: application/json" --json '{"key": "value"}'

但这样发送 JSON,需要在单引号和双引号之间切换,很快就会变得很烦人,但有一个更好的方法:

  • $ jo -p key=value | curl -X POST "https://httpbin.org/post" -H "accept: application/json" --json @-

我想我们都熟悉用 jq 解析 curl 的 JSON 输出,但反过来呢?

上面我们使用 jo 工具,它可以轻松创建 JSON,然后我们可以使用 --json 选项将其传递给 curl

当然,--json 选项也可以从文件中读取输入,例如使用 --json @data.json

协议

最后但同样重要的是协议 —— 通常我们只会使用 HTTP 或 HTTPS,但 curl 支持 很多协议

我特别想提到一个是 telnet,它对于测试服务器是否监听特定端口很有用,但如果你在一台没有安装也不能安装 telnet 的服务器/机器上怎么办?只需使用 curl

  • # 同 telnet example.com 1234
  • $ curl telnet://example.com:1234

一些更为冷门(有趣)的协议选项是用于电子邮件的 IMAP、POP3 和 SMTP,这意味着你可以使用 curl 阅读和发送电子邮件。要阅读它们:

  • $ curl --url "imaps://imap.gmail.com:993/Inbox;UID=1" --user "[email protected]:PASSWORD"

要使其在 GMail 上工作,你需要创建 应用密码,这比正常密码更不安全。如果你真的想尝试这个,请查看 Gmail IMAP 文档 和 这些查询 以获取灵感。

要发送电子邮件,你可以使用:

  • $ curl smtp://mail.example.com \
  • --mail-from [email protected] \
  • --mail-rcpt [email protected] \
  • --upload-file message.txt \
  • -u "[email protected]:PASSWORD"

这里的 message.txt 是实际的电子邮件,需要遵循特定格式,请查看 这个页面 了解示例。

结论

我们到了最后,我很确定这些例子至少有 10 个(我停止计数了)。但老实说,这只是冰山一角——我们甚至没有触及 curl 的重要级成部分 libcurl

curl 可以做的事情还有很多,所以我推荐你去探索 文档 和 https://everything.curl.dev/

城东书院 www.cdsy.xyz
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐