Curl 通常被认为是非交互式的网页浏览器。这意味着它能够从互联网上拉取信息,并在您的终端中显示或保存到文件中。这实际上就是网页浏览器(如 Firefox 或 Chromium)所做的事情,只不过它们默认情况下渲染信息,而 curl 下载并显示原始信息。实际上,curl 命令的功能远不止于此,它能够使用多种受支持的协议(包括 HTTP、FTP、SFTP、IMAP、POP3、LDAP、SMB、SMTP 以及更多)与服务器之间传输数据。对于普通终端用户来说,它是一个有用的工具;对于系统管理员来说,它是一种至关重要的便利;对于微服务和云开发人员来说,它是一个质量保证工具。
Curl 被设计为无需用户交互即可工作,因此与 Firefox 不同,您必须从头到尾考虑您与在线数据的交互。例如,如果您想在 Firefox 中查看网页,您需要启动一个 Firefox 窗口。在 Firefox 打开后,您需要将要访问的网站输入到 URL 字段或搜索引擎中。然后,您导航到该站点并单击您想要查看的页面。
相同的概念适用于 curl,只不过您一次性完成所有操作:您启动 curl 的同时,向其提供您想要的互联网位置,并告诉它您是否希望将数据保存在终端中还是文件中。当您必须与需要身份验证的站点或 API 交互时,复杂性会增加,但是一旦您学会了 curl 命令语法,它就会成为第二天性。为了帮助您掌握它,我们收集了相关的语法信息在一个方便的 速查表 中。
使用 curl 下载文件
您可以使用 curl 命令下载文件,方法是提供指向特定 URL 的链接。如果您提供的 URL 默认为 index.html,则会下载索引页,并且您下载的文件将显示在您的终端屏幕上。您可以将输出通过管道传递给 less 或 tail 或任何其他命令
$ curl "http://example.com" | tail -n 4
<h1>Example Domain</h1>
<p>This domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.</p>
<p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div></body></html>
因为某些 URL 包含您的 shell 通常会解释的特殊字符,所以最安全的做法是将您的 URL 放在引号中。
某些文件不太适合在终端中显示。您可以使用 --remote-name 选项来使文件按照其在服务器上的名称保存
$ curl --remote-name "https://example.com/linux-distro.iso"
$ ls
linux-distro.iso
或者,您可以使用 --output 选项将您的下载命名为您想要的任何名称
curl "http://example.com/foo.html" --output bar.html
使用 curl 列出远程目录的内容
因为 curl 是非交互式的,所以很难浏览页面以查找可下载的元素。前提是您连接到的远程服务器允许这样做,您可以使用 curl 列出目录的内容
$ curl --list-only "https://example.com/foo/"
继续部分下载
如果您正在下载一个非常大的文件,您可能会发现您必须中断下载。Curl 足够智能,可以确定您离开的位置并继续下载。这意味着下次您下载 4GB 的 Linux 发行版 ISO 时,如果出现问题,您永远不必回到起点。--continue-at 的语法有点不寻常:如果您知道下载中断的字节计数,您可以提供它;否则,您可以使用一个单独的破折号 (-) 来告诉 curl 自动检测它
$ curl --remote-name --continue-at - "https://example.com/linux-distro.iso"
下载文件序列
如果您需要下载多个文件——而不是仅仅一个大文件——curl 可以帮助您做到这一点。假设您知道您想要下载的文件的位置和文件名模式,您可以使用 curl 的序列表示法:整数范围的起点和终点,用方括号括起来。对于输出文件名,使用 #1 来指示第一个变量
$ curl "https://example.com/file_[1-4].webp" --output "file_#1.webp"
如果您需要使用另一个变量来表示另一个序列,请按照它在命令中出现的顺序表示每个变量。例如,在此命令中,#1 指的是目录 images_000 到 images_009,而 #2 指的是文件 file_1.webp 到 file_4.webp
$ curl "https://example.com/images_00[0-9]/file_[1-4].webp" \
--output "file_#1-#2.webp"
从站点下载所有 PNG 文件
您也可以进行一些基本的网页抓取来找到您想要下载的内容,仅使用 curl 和 grep。例如,假设您需要下载与您正在存档的网页关联的所有图像。首先,下载引用图像的页面。将页面通过管道传递给 grep,搜索您要定位的图像类型(在本例中为 PNG)。最后,创建一个 while 循环来构建下载 URL 并将文件保存到您的计算机
$ curl https://example.com |\
grep --only-matching 'src="[^"]*.[png]"' |\
cut -d\" -f2 |\
while read i; do \
curl https://example.com/"${i}" -o "${i##*/}"; \
done
这只是一个示例,但它演示了 curl 在与 Unix 管道和一些巧妙但基本的解析结合使用时,可以多么灵活。
获取 HTML 标头
用于数据交换的协议在计算机发送以进行通信的数据包中嵌入了大量元数据。HTTP 标头是数据初始部分的组成部分。在对站点的连接进行故障排除时,查看这些标头(尤其是响应代码)可能很有帮助
curl --head "https://example.com"
HTTP/2 200
accept-ranges: bytes
age: 485487
cache-control: max-age=604800
content-type: text/html; charset=UTF-8
date: Sun, 26 Apr 2020 09:02:09 GMT
etag: "3147526947"
expires: Sun, 03 May 2020 09:02:09 GMT
last-modified: Thu, 17 Oct 2019 07:18:26 GMT
server: ECS (sjc/4E76)
x-cache: HIT
content-length: 1256
快速失败
200 响应是 HTTP 通常表示成功的指示,所以这是您在联系服务器时通常期望的。著名的 404 响应表示找不到页面,而 500 表示服务器错误。
要查看协商期间发生的错误,请添加 --show-error 标志
$ curl --head --show-error "http://opensource.ga"
除非您可以访问您正在联系的服务器,否则这些错误可能很难修复,但 curl 通常会尽力解析您指向的位置。有时在网络上测试某些东西时,看似无休止的重试只会浪费时间,因此您可以使用 --fail-early 选项强制 curl 在失败时快速退出
curl --fail-early "http://opensource.ga"
按照 3xx 响应指定的重定向查询
然而,300 系列响应更加灵活。具体来说,301 响应意味着 URL 已永久移动到不同的位置。这是网站管理员重新定位内容,同时留下“踪迹”以便访问旧位置的人们仍然可以找到它的常用方法。Curl 默认情况下不遵循 301 重定向,但您可以使用 --location 选项使其继续到 301 目标位置
$ curl "https://iana.org" | grep title
<title>301 Moved Permanently</title>
$ curl --location "https://iana.org"
<title>Internet Assigned Numbers Authority</title>
展开缩短的 URL
当您想要在访问缩短的 URL 之前查看它们时,--location 选项非常有用。缩短的 URL 对于有字符限制的社交网络(当然,如果您使用现代和开源的社交网络,这可能不是问题)或用户无法复制和粘贴长 URL 的印刷媒体可能很有用。然而,它们也可能有点危险,因为它们的目的地本质上是隐藏的。通过结合 --head 选项来仅查看 HTTP 标头和 --location 选项来解开 URL 的最终目的地,您可以在不加载完整资源的情况下窥视缩短的 URL
$ curl --head --location \
"https://bit.ly/2yDyS4T"
下载我们的 curl 速查表
一旦您练习将探索网络的过程视为单个命令,curl 就会成为一种快速高效的方式,可以从互联网上获取您需要的信息,而无需麻烦使用图形界面。为了帮助您将其构建到您的日常工作流程中,我们创建了一个 curl 速查表,其中包含常见的 curl 用法和语法,包括使用它来查询 API 的概述。
7 条评论