掌握 cURL:高效下载文件与API交互的命令行利器

本文深入探讨了 cURL 命令行工具的使用,包括如何从Web服务器下载文件、处理重定向、实现认证、以及管理超时与中断下载。同时,文章对比了 cURL 和 wget 的使用场景,并提供了自动化下载和常见问题排查的指南,帮助开发者和运维人员高效地进行文件传输和API交互。

cURL (Client URL) 是一个功能强大且用途广泛的命令行工具和库,用于在系统之间传输数据。它支持多种协议,并且通常在类 Unix 操作系统中默认安装,这使其成为下载文件,尤其是在服务器环境中的理想选择。

本教程将详细指导您如何使用 curl 命令从 Web 服务器下载文件,涵盖了从查看内容、本地保存、处理重定向、处理认证到应对超时和中断下载等多种场景。无论您是需要与 REST API 交互,还是设置 Node.js 应用程序,curl 都是不可或缺的工具。

注意:从互联网下载文件始终存在风险。请务必确保从信誉良好的来源下载文件。在本教程中,我们将从 DigitalOcean 下载文件,并且不会执行任何下载的文件。

1. 获取远程文件内容

curl 命令在不带任何命令行参数的情况下运行时,会将获取到的文件内容直接显示到标准输出 (stdout)。这在您只想快速查看文件内容而不保存到本地时非常有用,例如查看 robots.txt 文件。

示例:下载 DigitalOcean 的 robots.txt 文件并显示其内容:

curl https://www.digitalocean.com/robots.txt

执行上述命令后,您将直接在终端中看到 robots.txt 的内容:

User-agent: *
Disallow:

sitemap: https://www.digitalocean.com/sitemap.xml
sitemap: https://www.digitalocean.com/community/main_sitemap.xml.gz
sitemap: https://www.digitalocean.com/community/questions_sitemap.xml.gz
sitemap: https://www.digitalocean.com/community/users_sitemap.xml.gz

2. 保存远程文件到本地

在许多情况下,您需要将远程文件保存到本地文件系统。curl 提供了两种主要方式来实现这一点。

使用原始文件名保存 (-O)

如果您希望将远程文件保存到本地系统,并使用与服务器上相同的原始文件名,可以使用 --remote-name 参数或其简写形式 -O (大写字母 “O”)。

示例:将 robots.txt 文件下载并保存为 robots.txt 到当前目录:

curl -O https://www.digitalocean.com/robots.txt

文件下载时,curl 将显示下载进度条,而不是文件内容。

使用指定文件名保存 (-o)

为了避免覆盖本地系统中可能存在的同名文件,或者您希望为下载的文件指定一个更具描述性的名称,可以使用 -o--output 参数,后跟您希望保存内容的文件名。

示例:将远程 robots.txt 文件下载并保存为 do-bots.txt

curl -o do-bots.txt https://www.digitalocean.com/robots.txt

3. 处理HTTP重定向

默认情况下,curl 不会自动跟随 HTTP 重定向。这意味着如果目标文件已移动(例如,从 HTTP 重定向到 HTTPS),您可能无法成功获取到期望的内容,而是收到一个重定向响应。

您可以使用 -I 标志查看请求头,以确认是否存在重定向响应(例如 HTTP 301 Moved Permanently 或 302 Found):

curl -I www.digitalocean.com/robots.txt

输出可能会显示 HTTP/1.1 301 Moved Permanently 以及 Location: https://www.digitalocean.com/robots.txt,表明存在重定向。

要让 curl 自动跟随重定向,请使用 --location 或其简写形式 -L 参数:

curl -L www.digitalocean.com/robots.txt

您可以将 -L 参数与 -o-O 结合使用来下载重定向后的文件:

curl -L -o do-bots.txt www.digitalocean.com/robots.txt

警告:许多在线资源会要求您使用 curl 下载脚本并直接执行它们。作为最佳实践,在运行任何下载的脚本之前,务必先检查其内容,确认其安全性,然后再使其可执行并运行。可以使用 less 命令审查代码,以确保它是您想要运行的内容。

4. 处理认证下载

curl 可以轻松处理需要认证才能访问的 Web 文件,这对于访问代理服务器或安全的 API 端点尤其有用。

基本认证 (Basic Authentication)

对于需要用户名和密码的基本认证,可以使用 -u 标志提供登录凭据:

curl -u username:password -O https://example.com/securefile.zip

基于令牌的认证 (Token-based Authentication)

对于基于 API 令牌的认证,通常需要通过 HTTP 头 (Header) 传递令牌。使用 -H 标志来添加自定义 HTTP 头:

curl -H "Authorization: Bearer YOUR_TOKEN" -O https://api.example.com/protected/data.json

为提高安全性,请避免在代码中硬编码敏感数据。推荐使用环境变量或配置文件来管理这些凭据。

5. 增强下载的健壮性:超时、重试与断点续传

在实际的网络环境中,网络中断和延迟是常见问题。curl 提供了多种选项来增强下载的健壮性,确保在不稳定条件下也能顺利完成任务。

恢复中断的下载 (断点续传)

当下载因网络中断或手动停止而中止时,可以使用 -C - 选项从中断处恢复下载。这会告诉 curl 从上次中断的地方继续下载,前提是服务器支持 HTTP 范围请求 (HTTP Range Requests)。

curl -C - -O https://example.com/largefile.iso

设置下载超时

为了防止 curl 命令无限期挂起(例如,当服务器响应缓慢或无响应时),可以使用 --max-time 设置最大允许时间(以秒为单位)。如果在此时间内未完成下载,curl 将终止。

curl --max-time 30 -O https://example.com/file.txt

重试失败的下载

网络瞬时故障可能导致下载失败。使用 --retry 选项可以自动重试失败的下载。您可以指定重试的次数,例如重试 3 次:

curl --retry 3 -O https://example.com/file.txt

6. 通过Shell脚本自动化下载

在 CI/CD 管道、定期备份或需要持续数据更新的应用程序(如 Node.js 应用程序或与 REST API 集成)中,自动化下载非常有用。将 curl 命令封装到 Shell 脚本中可以实现这一点。

示例脚本

#!/bin/bash
URL="https://example.com/file.zip"
DEST="/home/user/downloads/file.zip"
curl -L -o "$DEST" "$URL"

保存为 download_script.sh 后,使用 chmod +x download_script.sh 使脚本可执行。然后,您可以使用 cron 定时任务或在部署管道中安排它执行。

7. 常见下载问题排查

有时下载可能会失败或行为异常。以下是一些常见问题及其解决方案:

  • 文件未下载或下载内容异常
    • 使用 -I (Head 请求) 检查服务器响应头,确认文件是否存在、是否存在重定向或认证问题。
    • 尝试使用 -A "Mozilla/5.0" 模拟不同的用户代理 (User-Agent),某些服务器可能会根据 User-Agent 限制访问。
    • 使用 -v (Verbose 详细输出) 启用详细输出,以检查 SSL/TLS 证书问题、连接问题或 HTTP 错误。
    • 如果 HTTPS 连接失败,尝试使用 HTTP 协议 (如果可用且安全允许)。
    • 如果文件受保护,请使用 -u username:password-H "Authorization: ..." 提供正确的凭据。

详细输出 (-v) 对于识别问题的根源非常有帮助:

curl -v -O https://example.com/file.zip

8. cURL 与 Wget:选择合适的下载工具

虽然 curl 功能强大,但在某些下载场景中,wget 可能更合适。wget 专门设计用于下载文件,并具有一些特别有用的功能。

基本 wget 用法

下载文件:

wget https://example.com/file.zip

wget 的关键功能

  • 自动重试wget -t 3 https://example.com/file.zip (默认支持,curl 需要 --retry)
  • 后台下载wget -b https://example.com/file.zip (下载完成后可继续在后台运行)
  • 限制下载速度wget --limit-rate=200k https://example.com/file.zip
  • 递归下载 / 下载整个网站wget --mirror --convert-links --adjust-extension --page-requisites --no-parent https://example.com (此功能 curl 不直接支持)

何时选择 wget 而非 curl

  • 需要进行递归下载(例如,下载目录中的所有文件)。
  • 需要镜像 (Mirror) 整个网站或网站的一部分。
  • 需要内置的自动重试和断点续传功能(wget 在这方面更自动化)。
  • 寻求更简单的纯下载命令(wget 选项相对更侧重下载)。

何时坚持使用 curl

  • 需要与 RESTful API 进行复杂的交互(发送 JSON/XML 数据,自定义 HTTP 方法等)。
  • 进行更复杂的 HTTP 请求,例如发送 POST、PUT 请求。
  • 需要向服务器发送数据时。
  • 为了更好的脚本集成和更细粒度的控制 HTTP/HTTPS 协议细节时。
  • 当工具链中已经包含 curl 且不需要 wget 独有的递归下载功能时。

常见问题 (FAQ)

1. curl 中的 -O-o 有什么区别?

  • -O (大写字母 “O”):将下载的文件保存为服务器提供的原始文件名。
  • -o (小写字母 “o”):允许您为下载的文件指定一个自定义的文件名。

2. 如何使用 curl 恢复中断的下载?

使用 -C - 选项。这会告诉 curl 从上次中断的地方继续下载,前提是服务器支持 HTTP 范围请求。

3. 可以使用 curl 下载需要认证的文件吗?

可以。

  • 基本认证:curl -u username:password -O https://secure.example.com/file.zip
  • 基于令牌的认证:curl -H "Authorization: Bearer YOUR_TOKEN" -O https://api.example.com/file.zip 请务必避免在生产代码中硬编码敏感凭据。

4. 如果下载 URL 重定向怎么办?

使用 -L--location 选项,curl 将自动跟随重定向到新的位置。

5. cURL 在 Windows 上可用吗?

是的,cURL 在 Windows 10 及更高版本中通常默认包含。您也可以通过 Git Bash、Cygwin 或 Chocolatey (choco install curl) 等工具安装。

6. 如何使用 curl 同时下载多个文件?

可以通过列出多个 URL,或者使用大括号扩展来下载一系列文件:

  • 多个 URL: curl -O https://example.com/file1.zip -O https://example.com/file2.zip
  • 大括号扩展: curl -O https://example.com/file{1..5}.zip 您还可以使用包含 URL 列表的文本文件和 -K 选项。

7. 如何处理 curl 中的 SSL/TLS 证书问题?

不推荐用于生产环境,但可以使用 -k--insecure 选项绕过证书验证(这会使连接不安全)。更安全的方法是使用 --cacert /path/to/certificate.pem 指定自定义证书。

8. 如何使用 curl 监控下载进度和速度?

curl 默认会显示下载进度条。您可以使用 -# 显示一个简单的进度条,或者使用 -w 选项和各种变量(如 %{speed_download}%{time_total})来创建自定义的进度格式。

结论

curl 是一个功能强大且灵活的命令行工具,能够快速、可靠地从远程系统下载文件。它对多种协议的支持,使其成为文件传输和 API 交互的脚本友好型选择。从简单的文件下载到复杂的 API 请求,curl 能够处理自定义头部、认证、重定向和可恢复下载等所有操作。它是一款适用于开发人员、系统管理员和 DevOps 工程师的必备工具,因为它可以在不依赖重量级工具的情况下精确控制网络通信。

无论您是在 CI/CD 管道中自动化任务、集成来自外部源的数据,还是测试 REST API 或 Node.js 应用程序中的端点,curl 都能自然地融入现代开发工作流程。

要深入了解其所有功能,请运行 man curl 查看其完整的联机手册页 (man page)。

关于

关注我获取更多资讯

公众号
📢 公众号
个人号
💬 个人号
使用 Hugo 构建
主题 StackJimmy 设计