Curl 通常被认为是非交互式的 Web 浏览器。这意味着它能够从互联网上拉取信息,并在您的终端中显示或将其保存到文件中。这实际上就是 Web 浏览器(如 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 速查表
一旦您习惯于将探索 Web 的过程视为单个命令,curl 就会成为一种快速高效的方式,无需使用图形界面即可从互联网上获取您需要的信息。为了帮助您将其融入到您的日常工作流程中,我们创建了一个 curl 速查表,其中包含常见的 curl 用法和语法,包括使用它来查询 API 的概述。
7 条评论