Curl 是什么?一文看懂基础用法 – wiki基地


Curl 是什么?一文看懂基础用法

在当今高度互联的网络世界中,数据传输是核心。无论是简单的网页浏览、文件下载,还是复杂的API交互、系统调试,我们都需要可靠的工具来与远程服务器进行通信。在众多工具中,一个名字脱颖而出,成为开发者、系统管理员乃至普通用户手中的瑞士军刀——它就是 Curl

或许你已经在命令行中见过 curl 这个命令,或许你听过它的名字,但你真的了解它有多强大吗?本文将带你深入了解 Curl,从它的基本概念到丰富的常用功能,让你一文看懂 Curl 的核心用法。

第一章:揭开 Curl 的面纱 – 它到底是什么?

1.1 定义:数据传输的瑞士军刀

最核心地讲,curl 是一个命令行工具,用于利用 URL 的语法传输数据。它是一个开源项目,功能异常强大且灵活,支持极其广泛的网络协议。

它的全称实际上是 “Client for URLs”,即 URL 客户端。这恰如其分地描述了它的本质:作为一个客户端,它能够使用各种协议向服务器发送请求,并接收服务器返回的数据。

1.2 Curl 与 Libcurl:命令行工具与库

理解 Curl,必须同时理解 libcurllibcurl 是一个免费、易用的客户端 URL 传输库,支持几乎所有主流的传输协议。Curl 这个命令行工具正是基于 libcurl 库构建的。这意味着 libcurl 提供了底层的传输能力,而 curl 工具则为用户提供了一个方便易用的命令行接口来访问这些能力。

许多编程语言(如 Python, PHP, Node.js, Java 等)都有绑定库,允许开发者在其程序中直接调用 libcurl 的功能,实现数据传输。因此,Curl 的影响力不仅仅局限于命令行,它的核心库是许多应用程序网络通信的基础。

1.3 Curl 的核心能力:协议大阅兵

Curl 之所以强大,很大一部分原因在于它支持的协议种类繁多。这使得它几乎可以用于任何基于 URL 的数据传输场景。以下是 Curl 支持的一些主要协议(取决于编译时的配置):

  • HTTP / HTTPS: 这是最常用的协议,用于网页浏览、API 交互。Curl 对 HTTP/HTTPS 的支持非常完善,包括各种请求方法(GET, POST, PUT, DELETE 等)、头部处理、身份验证、Cookie、重定向等。
  • FTP / FTPS: 文件传输协议,用于上传和下载文件。
  • SFTP: SSH 文件传输协议,通过 SSH 连接进行安全的文件传输。
  • SCP: 安全拷贝协议,也通过 SSH 进行文件传输。
  • TELNET: 简单的交互式文本通信协议。
  • SMTP / SMTPS: 简单邮件传输协议,用于发送邮件。
  • POP3 / POP3S: 邮局协议版本3,用于接收邮件。
  • IMAP / IMAPS: 互联网邮件访问协议,用于管理和接收邮件。
  • SMB / SMB(S): 服务器消息块协议,用于 Windows 文件和打印机共享。
  • LDAP / LDAPS: 轻量级目录访问协议,用于访问目录服务。
  • FILE: 允许访问本地文件系统资源。
  • DICT: 字典网络协议。
  • GOPHER: 早期互联网信息检索协议。
  • RTMP: 实时消息传输协议,用于流媒体。
  • RTSP: 实时流协议,用于控制流媒体。

看到这个列表,你应该能理解为什么它被称为“瑞士军刀”了。无论是与 Web 服务器交互、管理远程文件、发送邮件,甚至是进行一些特殊的协议测试,Curl 都能胜任。

1.4 Curl 的优势与应用场景

  • 跨平台: Curl 几乎可以在所有操作系统上运行,包括 Linux、macOS、Windows 等。
  • 脚本友好: 作为一个命令行工具,Curl 非常适合集成到各种脚本中(Bash, Python, Perl 等),用于自动化任务。
  • 调试利器: 通过查看请求和响应的详细信息,Curl 是调试网络问题和 API 集成的绝佳工具。
  • 文件传输: 简单方便地上传和下载文件。
  • API 测试: 快速发送各种类型的 HTTP 请求,模拟客户端行为,测试 API 功能和性能。
  • 自动化任务: 定时抓取网页内容、监控网站状态、与远程服务交互等。

简而言之,任何需要通过 URL 与远程服务进行数据交换的场景,Curl 都可以派上用场。

第二章:安装与基础结构 – 开始使用 Curl

2.1 安装 Curl

在大多数现代操作系统中,Curl 都是预装的。你可以在终端或命令提示符中输入 curl --version 来检查 Curl 是否已安装以及其版本信息。

  • Linux: 大部分发行版都自带。如果未安装,可以使用包管理器安装,例如:
    bash
    sudo apt update && sudo apt install curl # Debian/Ubuntu
    sudo yum install curl # CentOS/RHEL
    sudo dnf install curl # Fedora
  • macOS: 自带。
  • Windows: 新版本的 Windows 10/11 自带。对于旧版本或未安装的情况,可以从官方网站下载安装包,或者使用包管理器如 Chocolatey 或 Scoop 安装。

2.2 Curl 命令的基本结构

一个典型的 Curl 命令通常遵循以下结构:

bash
curl [选项] [URL...]

  • curl: 命令本身。
  • [选项]: 用于修改 Curl 行为的标志。Curl 有数百个选项,用于控制协议、头部、数据、认证、输出、错误处理等各个方面。选项通常以单个短划线后跟一个字母(例如 -O)或双短划线后跟一个单词(例如 --output)表示。有些选项需要参数,例如 -o <文件名>--output <文件名>
  • [URL...]: 一个或多个要操作的 URL。Curl 会依次处理提供的 URL。

了解这个基本结构后,我们就可以开始探索 Curl 的核心用法了。

第三章:基础用法:获取数据与下载文件

3.1 最简单的请求:获取网页内容

Curl 最基本的用法就是获取指定 URL 的内容,并将其输出到标准输出(通常是终端)。

bash
curl http://example.com

执行这个命令,Curl 会向 http://example.com 发送一个 HTTP GET 请求,并将服务器返回的 HTML 内容直接显示在你的终端上。

同样,对于 HTTPS 网站也一样简单:

bash
curl https://www.baidu.com

Curl 会自动处理 HTTPS 的加密连接。

3.2 下载文件:保存到本地

将获取到的内容保存到文件是 Curl 的一个常见用途。Curl 提供了几个选项来完成这个任务。

3.2.1 -o <文件名>--output <文件名>:指定输出文件名

这个选项允许你将获取到的数据保存到指定的本地文件中。

bash
curl -o mypage.html http://example.com

这个命令会获取 http://example.com 的内容,并将其保存到当前目录下的 mypage.html 文件中。

下载一个二进制文件(如图片):

bash
curl -o linux_logo.png https://www.kernel.org/theme/images/logos/tux.png

3.2.2 -O--remote-name:使用远程文件名保存

如果你想将文件保存到本地,并使用 URL 中最后一部分作为文件名,可以使用 -O 选项。这在下载文件时特别方便,无需手动输入文件名。

bash
curl -O https://curl.se/logo/curl-logo.svg

这个命令会下载 curl-logo.svg 文件,并将其保存到当前目录下,文件名就是 curl-logo.svg

如果你要下载多个文件,可以列出多个 URL:

bash
curl -O http://example.com/file1.zip -O http://example.com/file2.tar.gz

Curl 会分别下载这两个文件,并以远程文件名 file1.zipfile2.tar.gz 保存到本地。

3.2.3 -L--location:处理重定向

许多网站在访问时会发生重定向(例如从 HTTP 重定向到 HTTPS,或从不带 www 的域名重定向到带 www 的)。默认情况下,Curl 不会自动跟随这些重定向。它只会告诉你发生了重定向(通常通过返回一个 3xx 状态码)。

要让 Curl 自动跟随重定向,你需要使用 -L 选项。这在下载文件或获取最终页面内容时非常重要。

bash
curl -L http://example.com

如果 http://example.com 重定向到 https://example.com,Curl 会自动向 https://example.com 发送新的请求并获取内容。

将重定向与文件下载结合:

bash
curl -L -O https://example.com/some/redirecting/file

Curl 会跟随重定向,直到找到最终的文件 URL,然后下载并以远程文件名保存该文件。

第四章:与服务器交互:发送不同类型的请求

Curl 不仅仅用于下载,它也是一个强大的工具,可以模拟客户端发送各种类型的 HTTP 请求,用于与 Web API 或服务进行交互。

4.1 指定请求方法:-X <方法>--request <方法>

默认情况下,Curl 使用 GET 方法。要发送其他类型的请求(如 POST, PUT, DELETE 等),需要使用 -X 选项。

发送 POST 请求:

bash
curl -X POST http://api.example.com/users

发送 DELETE 请求:

bash
curl -X DELETE http://api.example.com/users/123

虽然 -X 选项可以改变请求方法,但对于 POST 和 PUT 请求,通常还需要结合发送数据的选项(如 -d-F),Curl 会智能地根据是否提供了数据来决定使用 GET 还是 POST(如果你没有明确指定 -X POST)。然而,为了清晰和避免歧义,使用 -X 总是推荐的做法。

4.2 发送数据:-d <数据>--data <数据>

-d 选项用于发送 POST、PUT 等请求的请求体数据。它通常用于发送表单数据或 JSON 等格式的数据。

发送表单数据 (application/x-www-form-urlencoded):

当使用 -d 发送简单字符串数据时,Curl 默认会将 Content-Type 头部设置为 application/x-www-form-urlencoded,并对数据进行 URL 编码(空格变成 %20 等)。

bash
curl -X POST -d "username=testuser&password=testpass" http://api.example.com/login

你可以使用 @ 符号从文件中读取数据作为请求体:

bash
curl -X POST -d @data.txt http://api.example.com/submit

这里的 data.txt 文件内容将被用作 POST 请求的请求体。

发送 JSON 数据 (application/json):

如果 API 期望接收 JSON 数据,你可以直接在 -d 后面提供 JSON 字符串。然而,为了告诉服务器数据是 JSON 格式,通常还需要设置 Content-Type 头部。

bash
curl -X POST -H "Content-Type: application/json" -d '{"name": "Alice", "age": 30}' http://api.example.com/users

注意,这里的 JSON 字符串使用了单引号包围,以避免 shell 对双引号和其中的特殊字符进行解释。如果 JSON 字符串本身包含单引号,你需要进行适当的转义或使用其他引用方式。

4.3 发送表单数据(包含文件上传):-F <name=content>--form <name=content>

-F 选项用于构造 multipart/form-data 格式的请求体。这种格式常用于 HTML 表单提交,特别是在包含文件上传时。

发送一个简单的表单字段:

bash
curl -X POST -F "username=testuser" -F "password=testpass" http://api.example.com/login

这与 -d 发送 application/x-www-form-urlencoded 数据类似,但格式不同。

上传文件:使用 @ 符号指定文件路径。

bash
curl -X POST -F "profile_image=@/path/to/your/image.jpg" -F "description=My profile picture" http://api.example.com/upload

这个命令会模拟一个包含两个字段的表单提交:一个名为 profile_image 的文件字段(内容来自 /path/to/your/image.jpg)和一个名为 description 的普通文本字段。Curl 会自动设置 Content-Typemultipart/form-data

4.4 添加请求头:-H <Header: Value>--header <Header: Value>

自定义请求头是与服务器交互时非常常见的需求,例如发送认证令牌、指定内容类型、设置 User-Agent 等。-H 选项允许你添加任意数量的自定义头部。

设置 User-Agent 头部:

bash
curl -H "User-Agent: My Custom Curl Client/1.0" http://example.com

发送认证令牌 (Authorization 头部):

bash
curl -H "Authorization: Bearer your_access_token_here" http://api.example.com/secure-resource

指定接收的数据类型 (Accept 头部):

bash
curl -H "Accept: application/json" http://api.example.com/data

前面提到的发送 JSON 数据时设置 Content-Type 也是通过 -H 实现的:

bash
curl -X POST -H "Content-Type: application/json" -d '{"key": "value"}' http://api.example.com/resource

4.5 处理 Cookie:-c <文件>-b <文件>

Cookie 是网站用于跟踪用户会话状态的重要机制。Curl 可以发送和接收 Cookie。

  • -c <文件>--cookie-jar <文件>: 将 Curl 在请求过程中接收到的 Cookie 保存到指定的文件中。
  • -b <文件>--cookie <数据>: 在发送请求时包含指定文件中的 Cookie,或直接包含提供的 Cookie 字符串。

登录并保存 Cookie,然后用 Cookie 访问其他页面:

第一步:登录并保存 Cookie
bash
curl -c cookies.txt -d "username=test&password=pass" http://example.com/login

这个命令登录成功后,服务器返回的用于维护会话的 Cookie 将被保存到 cookies.txt 文件中。

第二步:使用保存的 Cookie 访问需要认证的页面
bash
curl -b cookies.txt http://example.com/profile

这个命令会读取 cookies.txt 中的 Cookie,并在访问 /profile 页面时将其包含在请求头中,服务器就能识别你的会话状态。

直接提供 Cookie 字符串:

bash
curl -b "sessionid=abcdef123456; username=testuser" http://example.com/somepage

第五章:认证与安全

与许多需要身份验证的服务交互时,Curl 提供了多种方式来处理。

5.1 基本认证:-u <user:password>--user <user:password>

对于使用 HTTP Basic Authentication 的服务,你可以使用 -u 选项提供用户名和密码。

bash
curl -u "myuser:mypassword" http://api.example.com/protected

Curl 会自动对用户名和密码进行 Base64 编码,并将其添加到 Authorization: Basic ... 头部中。

如果你省略密码,Curl 会在执行命令时提示你输入。

bash
curl -u "myuser" http://api.example.com/protected

Curl 会提示输入密码:Enter host password for user 'myuser':

5.2 处理 HTTPS 证书:-k--cacert

默认情况下,Curl 会验证 HTTPS 连接的服务器证书是否有效且受信任。如果证书有问题(例如自签名证书、过期证书或域名不匹配),Curl 会拒绝连接并报错。

  • -k--insecure: 警告: 这个选项会禁用 Curl 对服务器证书的验证。这意味着 Curl 会连接到任何提供了证书的服务器,即使这个证书是无效的或伪造的。这在测试环境或你知道证书有问题但信任服务器的情况下可能有用,但在生产环境或连接到不信任的网络时非常危险,因为它使你容易受到中间人攻击。

    bash
    curl -k https://localhost:8443/test # 在测试时可能需要忽略自签名证书

  • --cacert <文件>: 指定一个包含 CA 证书的文件(PEM 格式)。Curl 将使用这个 CA 证书文件来验证服务器证书。这在你需要连接到使用内部 CA 颁发的证书的服务器时很有用。

    bash
    curl --cacert /path/to/my/ca.pem https://internal-service.corp.com

最佳实践是使用 --cacert 或确保系统的 CA 证书库是最新的,而不是使用 -k

第六章:控制输出与调试

Curl 提供了丰富的选项来控制其输出以及获取详细的连接和传输信息,这对于调试非常有用。

6.1 静默模式:-s--silent

默认情况下,Curl 会显示一个进度条,指示传输的进度。在脚本中或只需要输出最终数据时,你可能希望禁用进度条和错误消息。

bash
curl -s http://example.com

这个命令只会将 example.com 的 HTML 内容输出到终端,不会显示任何进度信息。

6.2 显示错误(配合 -s):-S--show-error

当使用 -s 静默模式时,Curl 默认会抑制所有输出,包括错误信息。如果你想在静默模式下仅在发生错误时显示错误信息,可以使用 -S 选项。

bash
curl -s -S http://non-existent-domain.invalid

如果域名无法解析或服务器无法连接,这个命令会在终端输出相应的错误信息,但如果成功则完全静默。

6.3 显示进度条:-#--progress-bar

虽然默认有进度条,但 -# 选项提供了一个更简单、更直接的进度条显示,特别适合下载大文件时使用。

bash
curl -# -O https://example.com/largefile.zip

6.4 详细输出:-v--verbose

这是 Curl 最重要的调试选项之一。-v 会显示 Curl 在连接、请求和传输过程中进行的所有操作,包括:

  • 连接的 IP 地址和端口
  • SSL/TLS 握手信息
  • 发送的完整请求头
  • 接收到的完整响应头
  • 传输的数据摘要

bash
curl -v http://example.com

执行这个命令,你会在终端看到详细的握手过程、请求头(以 > 开头)、响应头(以 < 开头)以及最终的 HTML 内容。这对于理解 Curl 的行为、查看实际发送的请求以及服务器的响应细节至关重要。

6.5 仅显示头部:-I--head

-I 选项只会发送一个 HEAD 请求,并仅显示响应头。HEAD 请求类似于 GET 请求,但服务器不会在响应中返回请求体(例如网页内容)。这常用于检查文件是否存在、获取文件大小、修改时间等信息,而无需下载整个文件。

bash
curl -I http://example.com

输出示例:
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: max-age=604800
Content-Type: text/html; charset=UTF-8
Date: Mon, 18 Oct 2023 10:00:00 GMT
Etag: "3147526947"
Expires: Mon, 25 Oct 2023 10:00:00 GMT
Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
Server: ECS (sec/99A)
Vary: Accept-Encoding
X-Cache: HIT
Content-Length: 1256

6.6 仅显示响应体:-N--no-buffer (配合 -s)

默认情况下,Curl 会尝试缓冲输出。当你只需要响应体且不想看到任何其他信息时,可以结合 -s 和其他选项。例如,要仅获取并输出页面的 HTML 内容:

bash
curl -s http://example.com

这通常已经足够。-N 主要用于禁用缓冲,在某些特定场景下可能有用,但在基本用法中不如 -s-v 常用。

6.7 显示详细信息:-w <格式字符串>--write-out <格式字符串>

-w 选项非常强大,允许你在请求完成后按照指定的格式输出关于传输的信息,如状态码、总时间、下载速度、请求 URL 等。这在自动化脚本中用来获取请求结果的元数据非常有用。

例如,获取 HTTP 状态码:

bash
curl -s -o /dev/null -w "%{http_code}\n" http://example.com

解释:
* -s: 静默模式,不输出进度和 HTML 内容。
* -o /dev/null: 将实际的 HTML 内容重定向到空设备,不显示或保存。
* -w "%{http_code}\n": 在请求完成后,输出状态码(%{http_code} 是一个变量),并在末尾加上换行符。

输出可能是 200404 等。

获取更多信息,如总时间、大小、速度:

bash
curl -s -o /dev/null -w "Status: %{http_code}\nTotal time: %{time_total} s\nDownload speed: %{speed_download} B/s\n" http://example.com

-w 选项支持很多变量,通过 curl --write-out help 可以查看完整的列表。

第七章:其他常用功能

除了上述核心用法,Curl 还有一些其他在日常任务中非常有用的功能。

7.1 设置连接超时:--connect-timeout--max-time

控制 Curl 等待连接建立或整个传输完成的时间可以防止脚本无限期挂起。

  • --connect-timeout <秒>: 设置连接阶段的超时时间。如果在指定秒数内无法建立连接,Curl 会放弃。
  • --max-time <秒>: 设置整个传输过程允许花费的最大时间。如果传输时间超过这个限制,Curl 会中止。

bash
curl --connect-timeout 5 --max-time 10 http://slow-server.example.com

这个命令将连接超时设置为 5 秒,总超时时间设置为 10 秒。

7.2 限制下载速度:--limit-rate <速度>

如果你想限制 Curl 的下载或上传速度,可以使用 --limit-rate。这在避免 Curl 占用过多带宽时很有用。

bash
curl --limit-rate 100K -O http://example.com/largefile.zip

这个命令将下载速度限制在 100 KB/秒。你可以使用 k (KB)、m (MB)、g (GB) 单位。

7.3 断点续传:-C ---continue-at -

当下载大文件中断后,你可以使用 -C - 选项尝试从上次中断的地方继续下载。Curl 会自动检测本地已下载的部分,并发送 Range 请求给服务器,从断点处继续下载。

bash
curl -C - -O http://example.com/hugefile.tar.gz

注意,这需要服务器支持 Range 请求。大多数现代 Web 服务器都支持。

7.4 使用代理:-x <代理地址>--proxy <代理地址>

Curl 可以通过代理服务器进行连接。

bash
curl -x http://your.proxy.com:8080 http://example.com

你也可以指定需要认证的代理:

bash
curl -x http://user:[email protected]:8080 http://example.com

Curl 支持多种代理协议,如 HTTP、SOCKS 等。

7.5 保存头部到文件:-D <文件>--dump-header <文件>

-v 会将头部信息输出到标准错误不同,-D 选项可以将接收到的响应头部直接保存到指定文件中。

bash
curl -D headers.txt http://example.com

这会将 example.com 的响应头部保存到 headers.txt 文件中,而页面的主体内容则正常输出到终端。

第八章:为什么 Curl 对开发者和系统管理员至关重要?

读到这里,你可能已经对 Curl 的能力有了初步的认识。它的价值不仅仅在于能够传输数据,更在于它为复杂任务提供的便利性和灵活性。

  • API 开发与测试: 开发者可以使用 Curl 轻松模拟各种 API 请求,测试不同的参数、头部和认证方式。结合 -v 可以深入了解请求和响应的细节,快速定位问题。
  • 后端服务交互: 在没有现成客户端库的情况下,或者需要进行简单的调试时,Curl 可以快速地与远程后端服务(如数据库、消息队列的 HTTP 接口等)进行交互。
  • 自动化脚本: Curl 是 Shell 脚本中进行网络操作的标准工具。无论是定时下载数据、检查网站状态、触发远程任务,Curl 都能完美集成。
  • 网络故障排除: 当遇到网络连接问题、服务器无响应、重定向错误等问题时,使用 Curl 配合 -v 选项可以非常有效地诊断问题所在,确定是客户端、网络还是服务器端的问题。
  • 性能测试: 虽然 Curl 不是专业的性能测试工具,但结合 -w 选项获取时间信息,可以对简单的请求进行初步的性能测量。
  • 学习网络协议: 通过 -v 选项,你可以清晰地看到 HTTP/HTTPS 请求和响应的完整过程,这对于学习网络协议非常有帮助。

对于任何与网络打交道的人来说,熟练掌握 Curl 都是一项非常有价值的技能。它提供了一种直接、透明的方式来观察和控制网络通信过程。

结论

Curl 是一个功能极其强大且用途广泛的命令行工具,是进行网络数据传输的瑞士军刀。它支持广泛的协议,提供了丰富的选项来精细控制请求和响应的各个方面。

本文介绍了 Curl 的基本概念、安装方法,以及最核心的用法,包括:

  • 获取网页内容
  • 下载文件 (-o, -O, -L)
  • 发送不同请求方法 (-X)
  • 发送请求体数据 (-d, -F)
  • 添加自定义头部 (-H)
  • 处理 Cookie (-c, -b)
  • 处理认证 (-u)
  • 控制输出与调试 (-s, -S, -#, -v, -I, -w)
  • 设置超时 (--connect-timeout, --max-time)
  • 断点续传 (-C -)
  • 使用代理 (-x)

这仅仅是 Curl 功能的冰山一角。Curl 拥有多达数百个选项,能够处理更复杂的场景,如多线程下载、FTP 文件管理、证书管理、请求限速、IPv6、 socks 代理等等。

掌握了本文介绍的基础用法,你已经能够应对绝大多数日常的网络交互任务。当你遇到更复杂的场景时,可以查阅 Curl 的官方文档(man curl 或在线文档)来发现更多强大的功能和选项。

现在,打开你的终端,尝试使用 curl 命令吧!通过实践,你将越来越熟悉这个强大工具的魅力。Curl 将成为你在网络世界中不可或缺的得力助手。


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部