193. Linux中的命令之下载

wget

Linux wget是一个下载文件的工具,它用在命令行下,对于Linux用户是必不可少的工具,尤其对于网络管理员,经常要下载一些软件或从远程服务器恢复备份到本地服务器。

wget工具体积小但功能完善,它支持断点续传功能,同时支持ftp和http下载方式,支持代理服务器,设置起来方便简单。

使用wget下载文件

你可以通过给定一个地址来使用wget下载文件,如果你提供的地址默认指向index.html, 那么这个index页面将会被下载。默认情况下,该文件会以相同的命名下载到当前工作目录中。

1
2
3
4
5
6
7
$ wget http://example.com
--2021-09-20 17:23:47-- http://example.com/
Resolving example.com... 93.184.216.34, 2606:2800:220:1:248:1893:25c8:1946
Connecting to example.com|93.184.216.34|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1256 (1.2K) [text/html]
Saving to: 'index.html'

你可以使用 --output-document 和一个破折号 - 让wget将数据输出到标准输出(stdout):

1
2
3
4
5
$ wget http://example.com --output-document - | head -n4
<!doctype html>
<html>
<head>
<title>Example Domain</title>

你可以使用 --output-document(简写为 -O)重新命名你下载的文件:

1
$ wget http://example.com --output-document foo.html

断点续传

如果你正在下载一个非常大的文件,而你不得不中断下载,那么可以使用 --continue (简写为 -c) 命令, wget可以确定下载停止的位置并在这个位置上继续下载。这意味着下次下载4GB的 Linux ISO文件时,如果出现问题,就不必从头开始。

1
$ wget --continue https://example.com/linux-distro.iso

下载文件集

如果你需要下载的不是一个大文件而是几个文件,wget可以帮助你。假设你知道要下载的文件的位置和文件名模式,可以使用Bash语法指定一系列整数之间的起点和终点,以表示一系列文件名:

1
$ wget http://example.com/file_{1..4}.webp

镜像(下载)整个站点

你可以使用 --mirror 选项下载整个站点,包括其目录结构。这个选项与运行 --recursive --level inf --timestamping --no-remove-listing 相同,这意味着它是无限递归的,因此你可以获得指定站点上的所有内容。

如果你使用 wget 来下载一个站点,那么选项 --no-cookies --page-requisites --convert-links 可以确保每个页面都是完整的,并且站点副本或多或少都是独立的。

修改HTML头

用于数据交换的协议在计算机发送用于通信的数据包中嵌入了大量元数据。HTTP 头是数据初始部分的组件。浏览网站时,浏览器会发送 HTTP 请求头。使用 --debug 选项查看 wget 随每个请求发送的标头信息:

1
2
3
4
5
6
7
8
9
10
$ wget --debug example.com
---request begin---
GET / HTTP/1.1
User-Agent: Wget/1.19.5 (linux-gnu)
Accept: */*
Accept-Encoding: identity
Host: example.com
Connection: Keep-Alive

---request end---

你可以使用 --header 选项修改请求头。比如,在模拟特定浏览器的时候很非常有用,无论是用于测试,还是用于只对于特定的代理用户能访问的站点。

要标识为在Windows上运行的Microsoft Edge,请执行以下操作:

1
$ wget --debug --header="User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.59" http://example.com

你还可以伪装成特定的移动设备:

1
2
3
$ wget --debug \
--header="User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Mobile/15E148 Safari/604.1" \
http://example.com

查看响应头

与浏览器请求头的方式相同,头信息也包含在响应中。可以使用 –debug 查看响应头:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ wget --debug example.com
[...]
---response begin---
HTTP/1.1 200 OK
Accept-Ranges: bytes
Age: 188102
Cache-Control: max-age=604800
Content-Type: text/html; charset=UTF-8
Etag: "3147526947"
Server: ECS (sab/574F)
Vary: Accept-Encoding
X-Cache: HIT
Content-Length: 1256
---response end---
200 OK
Registered socket 3 for persistent reuse.
URI content encoding = 'UTF-8'
Length: 1256 (1.2K) [text/html]
Saving to: 'index.html'

响应301

响应代码200意味着一切都按预期进行,代码301表示所访问的地址已经移动到了其他位置。网站管理员通常会留下“线索”的同时重新定位内容,以便访问旧位置的人仍然可以找到它。默认情况下,wget 遵循重定向,这也是我们所希望的。

但是,你可以控制 wget 在遇到301响应的时候,不执行重定向,通过使用 --max-redirect 选项来实现(将其设置为0):

1
2
3
4
5
6
7
$ wget --max-redirect 0 http://iana.org
--2021-09-21 11:01:35-- http://iana.org/
Resolving iana.org... 192.0.43.8, 2001:500:88:200::8
Connecting to iana.org|192.0.43.8|:80... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://www.iana.org/ [following]
0 redirections exceeded.

或者,你可以将其设置为其他数字,以控制wget接下来的重定向数量。

展开缩短的URL

--max-redirect 选项在实际访问一个缩短的URL之前查看它们非常有用。缩短的URL对于印刷媒体很有用,在印刷媒体中,或者在有字符限制的社交网络上(这在像Mastodon这样的现代开源社交网络上并不是一个问题),用户不能只复制和粘贴一个长的URL。然而,它们也可能有点危险,因为它们的目的地(实际地址)是隐蔽的。结合--head 选项查看HTTP头信息,以及--location 选项解开一个URL的最终地址,你可以在不加载完整资源的情况下查看缩短的URL:

1
2
3
4
5
6
7
$ wget --max-redirect 0 "https://bit.ly/2yDyS4T"
--2021-09-21 11:32:04-- https://bit.ly/2yDyS4T
Resolving bit.ly... 67.199.248.10, 67.199.248.11
Connecting to bit.ly|67.199.248.10|:443... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: http://example.com/ [following]
0 redirections exceeded.

倒数第二行的输出,从Location开始,显示真实的地址。

当你开始练习将浏览web的过程作为一个命令进行思考,wget就成为了一种快速有效的方法,可以从Internet中提取你需要的信息,而无需使用图形界面。

示例

例子1:使用wget下载单个文件

以下代码从网络下载一个文件并保存在当前目录中。

1
$ cd /opt$ wget http://mirrors.sohu.com/centos/7.4.1708/isos/x86_64/CentOS-7-x86_64-Minimal01708.iso

在下载过程中会显示进度条,包含(下载完成百分比、已经下载的字节、当前下载速度、剩余下载时间)。

例子2:使用 wget -O 下载并以不同的文件名保存

下面的例子会下载一个文件并以名称CentOS-7-x86_64-Minimal-1708.iso保存

1
$ wget http://mirrors.sohu.com/centos/7.4.1708/isos/x86_64/CentOS-7-x86_64-Minimal-1708.iso

文件名称太长不方便运维人员操作,可以自定义文件名称。为了解决此问题,可以使用 -O 来指定一个文件名,如下代码:

1
$ wget -O CentOS7_4_mini.iso http://mirrors.sohu.com/centos/7.4.1708/isos/x86_64/CentOS-7-x86_64-Minimal-1708.iso

例子3:使用wget --limit-rate限速下载

运行wget指令下载文件时,默认会占用全部可能的带宽进行下载操作,当准备下载一个大文件时,可以根据需要进行限速控制。

1
$ wget -O CentOS7_4_mini.iso --limit-rate=600k http://mirrors.sohu.com/centos/7.4.1708/isos/x86_64/CentOS-7-x86_64-Minimal-1708.iso

例子4:断点续传

使用wget -c指令可以重新启动下载过程中断的文件

1
wget -c http://mirrors.sohu.com/centos/7.4.1708/isos/x86_64/CentOS-7-x86_64-Minimal01708.iso

下载大文件时,如果突然由于网络等原因终端,断点续传会非常有帮助,可以继续接着下载而不是重新下载一个文件,需要继续终端的下载可以使用 -c 选项。

例子5:使用wget -b 后台下载

在下载非常大的文件时,可以使用选项 -b 后台下载。

1
$wget -b http://mirrors.sohu.com/centos/7.4.1708/isos/x86_64/CentOS-7-x86_64-Minimal01708.iso

例子6:伪装代理名称下载

有些网站能通过根据判断代理名称不是浏览器而拒绝你的下载请求,可以通过--user-agent选项伪装。

1
$wget --user-agent="Mozilla/5.0(Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16" http://mirrors.sohu.com/centos/7.4.1708/isos/x86_64/CentOS-7-x86_64-Minimal01708.iso

例子7:测试下载连接

有定时下载任务时,应在预定时间测试下载连接是否有效,可以增加 --spider 选项进行检查。

1
$ wget --spider URL

如果下载连接正确,会有”Remote file exists.”信息提示。

大家可以在以下几种情况下使用spider选项:

1)定时下载之前进行检查;

2)间隔检测网站是否可用;

3)检查网站页面的死链接。

例子8:使用wget --tries增加重试次数

如果网络有问题或下载一个大文件,也有可能失败。wget默认重试20次连接下载文件。如果需要,可以使用--tries增加重试次数。

1
$ wget --tries=30 URL

例子9:使用 wget -i 下载多个文件

首先,保存一份下载链接文件:

1
2
3
4
5
cat >iso_list.txt<<a
URL1
URL2
URL3
a

接着使用这个文件和选项-i下载:

1
$ wget -i iso_list.txt

例子9:使用wget做网站镜像

如下示例为下载整个网站到本地:

1
$ wget --mirror -p --convert-links -p ./LOCAL URL
  • --mirror: 设置这个参数来建立本地镜像;
  • -p: 下载所有html文件适合显示的元素;
  • --convert-links: 下载完成后,将文档连接都转换成本地的;
  • -P ./LOCAL-DIR: 保存所有的文件和目录到指定文件夹下。

例子10:过滤指定格式下载

下载站点时,不下载gif动画图片:

1
$ wget --reject-gif URL

例子11:使用 wget -o 把下载信息存入日志文件

下载信息不直接显示在终端,而是在一个日志文件中,使用小写字母o,如下代码所示:

1
$ wget -o download.log URL

例子12:使用 wget -Q 限制总下载文件大小

下载的文件超过10MB而退出下载,可以使用如下指令:

1
$ wget -Q10m -i iso_list.txt

注意:此选项对单个文件下载不起作用,只能递归下载时才有效。

例子13:下载指定格式文件

可以在以下场景使用该功能:

1)下载一个网站的所有图片;

2)下载一个网站的所有视频;

3)下载一个网站的所有pdf文件。

1
$ wget -r -A.pdf URL

从一个网站下载所有pdf文件。

例子14:使用wget ftp下载

可以使用wget完成ftp链接的下载,匿名ftp下载类似于http下载。

1
$ wget ftp-url

如果要输入用户名和密码,则使用wget用户名和密码认证的ftp下载:

1
$ wget --ftp-user=USERNAME --ftp-password=PASSWORD URL

curl

什么是 curl

curl 是一种数据传输工具。它可以作为开发库和基于终端的 cli 来使用,两者都有相同的引擎(事实是,cli 工具只是在开发库下的一个程序)。

curl 适用于你可能使用的每个协议。

curl 能做什么

与数据传输有关的所有事情(都可以用curl)。每个人都用过浏览器(比如你正在使用浏览器阅读本文),浏览器所做的就是请求一个页面,并得到响应,它可以写入和读取cookie,然后渲染(显示内容、图像和执行js脚本)。

除了最后一步渲染以外(因为它与数据传输无关),curl 可以做所有浏览器所做的工作。

总之,curl 可以下载html页面,可以填充并且提交 html 表单,可以从 FTP/HTTP 服务器下载、上传文件,还可以读写 cookie

这使得它成为脚本编写、调试和取证分析等方面的优秀工具。

curl 命令实例

我们来看看可以用 curl 做什么

参数概览, 可通过 curl --help allman curl 获取当前终端版本支持的参数. 下面是先在 MacOS 系统的参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
Usage: curl [options...] <url>
--abstract-unix-socket <path> Connect via abstract Unix domain socket
--alt-svc <filename> Enable alt-svc with this cache file
--anyauth Pick any authentication method
-a, --append Append to target file when uploading
--aws-sigv4 <provider1[:prvdr2[:reg[:srv]]]> AWS V4 signature auth
--basic HTTP Basic Authentication
--ca-native Load CA certs from the OS
--cacert <file> CA certificate to verify peer against
--capath <dir> CA directory to verify peer against
-E, --cert <certificate[:password]> Client certificate file and password
--cert-status Verify server cert status OCSP-staple
--cert-type <type> Certificate type (DER/PEM/ENG/P12)
--ciphers <list of ciphers> SSL ciphers to use
--compressed Request compressed response
--compressed-ssh Enable SSH compression
-K, --config <file> Read config from a file
--connect-timeout <seconds> Maximum time allowed to connect
--connect-to <HOST1:PORT1:HOST2:PORT2> Connect to host
-C, --continue-at <offset> Resumed transfer offset
-b, --cookie <data|filename> Send cookies from string/load from file
-c, --cookie-jar <filename> Save cookies to <filename> after operation
--create-dirs Create necessary local directory hierarchy
--create-file-mode <mode> File mode for created files
--crlf Convert LF to CRLF in upload
--crlfile <file> Certificate Revocation list
--curves <list> (EC) TLS key exchange algorithms to request
-d, --data <data> HTTP POST data
--data-ascii <data> HTTP POST ASCII data
--data-binary <data> HTTP POST binary data
--data-raw <data> HTTP POST data, '@' allowed
--data-urlencode <data> HTTP POST data URL encoded
--delegation <LEVEL> GSS-API delegation permission
--digest HTTP Digest Authentication
-q, --disable Disable .curlrc
--disable-eprt Inhibit using EPRT or LPRT
--disable-epsv Inhibit using EPSV
--disallow-username-in-url Disallow username in URL
--dns-interface <interface> Interface to use for DNS requests
--dns-ipv4-addr <address> IPv4 address to use for DNS requests
--dns-ipv6-addr <address> IPv6 address to use for DNS requests
--dns-servers <addresses> DNS server addrs to use
--doh-cert-status Verify DoH server cert status OCSP-staple
--doh-insecure Allow insecure DoH server connections
--doh-url <URL> Resolve hostnames over DoH
-D, --dump-header <filename> Write the received headers to <filename>
--egd-file <file> EGD socket path for random data
--engine <name> Crypto engine to use
--etag-compare <file> Load ETag from file
--etag-save <file> Parse incoming ETag and save to a file
--expect100-timeout <seconds> How long to wait for 100-continue
-f, --fail Fail fast with no output on HTTP errors
--fail-early Fail on first transfer error
--fail-with-body Fail on HTTP errors but save the body
--false-start Enable TLS False Start
-F, --form <name=content> Specify multipart MIME data
--form-escape Escape form fields using backslash
--form-string <name=string> Specify multipart MIME data
--ftp-account <data> Account data string
--ftp-alternative-to-user <command> String to replace USER [name]
--ftp-create-dirs Create the remote dirs if not present
--ftp-method <method> Control CWD usage
--ftp-pasv Send PASV/EPSV instead of PORT
-P, --ftp-port <address> Send PORT instead of PASV
--ftp-pret Send PRET before PASV
--ftp-skip-pasv-ip Skip the IP address for PASV
--ftp-ssl-ccc Send CCC after authenticating
--ftp-ssl-ccc-mode <active/passive> Set CCC mode
--ftp-ssl-control Require TLS for login, clear for transfer
-G, --get Put the post data in the URL and use GET
-g, --globoff Disable URL globbing with {} and []
--happy-eyeballs-timeout-ms <ms> Time for IPv6 before IPv4
--haproxy-clientip <ip> Set address in HAProxy PROXY
--haproxy-protocol Send HAProxy PROXY protocol v1 header
-I, --head Show document info only
-H, --header <header/@file> Pass custom header(s) to server
-h, --help <category> Get help for commands
--hostpubmd5 <md5> Acceptable MD5 hash of host public key
--hostpubsha256 <sha256> Acceptable SHA256 hash of host public key
--hsts <filename> Enable HSTS with this cache file
--http0.9 Allow HTTP 0.9 responses
-0, --http1.0 Use HTTP 1.0
--http1.1 Use HTTP 1.1
--http2 Use HTTP/2
--http2-prior-knowledge Use HTTP 2 without HTTP/1.1 Upgrade
--http3 Use HTTP v3
--http3-only Use HTTP v3 only
--ignore-content-length Ignore the size of the remote resource
-i, --include Include response headers in output
-k, --insecure Allow insecure server connections
--interface <name> Use network INTERFACE (or address)
--ipfs-gateway <URL> Gateway for IPFS
-4, --ipv4 Resolve names to IPv4 addresses
-6, --ipv6 Resolve names to IPv6 addresses
--json <data> HTTP POST JSON
-j, --junk-session-cookies Ignore session cookies read from file
--keepalive-time <seconds> Interval time for keepalive probes
--key <key> Private key filename
--key-type <type> Private key file type (DER/PEM/ENG)
--krb <level> Enable Kerberos with security <level>
--libcurl <file> Generate libcurl code for this command line
--limit-rate <speed> Limit transfer speed to RATE
-l, --list-only List only mode
--local-port <range> Use a local port number within RANGE
-L, --location Follow redirects
--location-trusted Like --location, but send auth to other hosts
--login-options <options> Server login options
--mail-auth <address> Originator address of the original email
--mail-from <address> Mail from this address
--mail-rcpt <address> Mail to this address
--mail-rcpt-allowfails Allow RCPT TO command to fail
-M, --manual Display the full manual
--max-filesize <bytes> Maximum file size to download
--max-redirs <num> Maximum number of redirects allowed
-m, --max-time <seconds> Maximum time allowed for transfer
--metalink Process given URLs as metalink XML file
--negotiate Use HTTP Negotiate (SPNEGO) authentication
-n, --netrc Must read .netrc for username and password
--netrc-file <filename> Specify FILE for netrc
--netrc-optional Use either .netrc or URL
-:, --next Make next URL use its separate set of options
--no-alpn Disable the ALPN TLS extension
-N, --no-buffer Disable buffering of the output stream
--no-clobber Do not overwrite files that already exist
--no-keepalive Disable TCP keepalive on the connection
--no-npn Disable the NPN TLS extension
--no-progress-meter Do not show the progress meter
--no-sessionid Disable SSL session-ID reusing
--noproxy <no-proxy-list> List of hosts which do not use proxy
--ntlm HTTP NTLM authentication
--ntlm-wb HTTP NTLM authentication with winbind
--oauth2-bearer <token> OAuth 2 Bearer Token
-o, --output <file> Write to file instead of stdout
--output-dir <dir> Directory to save files in
-Z, --parallel Perform transfers in parallel
--parallel-immediate Do not wait for multiplexing (with --parallel)
--parallel-max <num> Maximum concurrency for parallel transfers
--pass <phrase> Pass phrase for the private key
--path-as-is Do not squash .. sequences in URL path
--pinnedpubkey <hashes> FILE/HASHES Public key to verify peer against
--post301 Do not switch to GET after a 301 redirect
--post302 Do not switch to GET after a 302 redirect
--post303 Do not switch to GET after a 303 redirect
--preproxy [protocol://]host[:port] Use this proxy first
-#, --progress-bar Display transfer progress as a bar
--proto <protocols> Enable/disable PROTOCOLS
--proto-default <protocol> Use PROTOCOL for any URL missing a scheme
--proto-redir <protocols> Enable/disable PROTOCOLS on redirect
-x, --proxy [protocol://]host[:port] Use this proxy
--proxy-anyauth Pick any proxy authentication method
--proxy-basic Use Basic authentication on the proxy
--proxy-ca-native Load CA certs from the OS to verify proxy
--proxy-cacert <file> CA certificates to verify proxy against
--proxy-capath <dir> CA directory to verify proxy against
--proxy-cert <cert[:passwd]> Set client certificate for proxy
--proxy-cert-type <type> Client certificate type for HTTPS proxy
--proxy-ciphers <list> SSL ciphers to use for proxy
--proxy-crlfile <file> Set a CRL list for proxy
--proxy-digest Digest auth with the proxy
--proxy-header <header/@file> Pass custom header(s) to proxy
--proxy-http2 Use HTTP/2 with HTTPS proxy
--proxy-insecure Skip HTTPS proxy cert verification
--proxy-key <key> Private key for HTTPS proxy
--proxy-key-type <type> Private key file type for proxy
--proxy-negotiate HTTP Negotiate (SPNEGO) auth with the proxy
--proxy-ntlm NTLM authentication with the proxy
--proxy-pass <phrase> Pass phrase for the private key for HTTPS proxy
--proxy-pinnedpubkey <hashes> FILE/HASHES public key to verify proxy with
--proxy-service-name <name> SPNEGO proxy service name
--proxy-ssl-allow-beast Allow security flaw for interop for HTTPS proxy
--proxy-ssl-auto-client-cert Auto client certificate for proxy
--proxy-tls13-ciphers <ciphersuite list> TLS 1.3 proxy cipher suites
--proxy-tlsauthtype <type> TLS authentication type for HTTPS proxy
--proxy-tlspassword <string> TLS password for HTTPS proxy
--proxy-tlsuser <name> TLS username for HTTPS proxy
--proxy-tlsv1 TLSv1 for HTTPS proxy
-U, --proxy-user <user:password> Proxy user and password
--proxy1.0 <host[:port]> Use HTTP/1.0 proxy on given port
-p, --proxytunnel HTTP proxy tunnel (using CONNECT)
--pubkey <key> SSH Public key filename
-Q, --quote <command> Send command(s) to server before transfer
--random-file <file> File for reading random data from
-r, --range <range> Retrieve only the bytes within RANGE
--rate <max request rate> Request rate for serial transfers
--raw Do HTTP raw; no transfer decoding
-e, --referer <URL> Referrer URL
-J, --remote-header-name Use the header-provided filename
-O, --remote-name Write output to file named as remote file
--remote-name-all Use the remote filename for all URLs
-R, --remote-time Set remote file's time on local output
--remove-on-error Remove output file on errors
-X, --request <method> Specify request method to use
--request-target <path> Specify the target for this request
--resolve <[+]host:port:addr[,addr]...> Resolve host+port to address
--retry <num> Retry request if transient problems occur
--retry-all-errors Retry all errors (with --retry)
--retry-connrefused Retry on connection refused (with --retry)
--retry-delay <seconds> Wait time between retries
--retry-max-time <seconds> Retry only within this period
--sasl-authzid <identity> Identity for SASL PLAIN authentication
--sasl-ir Initial response in SASL authentication
--service-name <name> SPNEGO service name
-S, --show-error Show error even when -s is used
-s, --silent Silent mode
--socks4 <host[:port]> SOCKS4 proxy on given host + port
--socks4a <host[:port]> SOCKS4a proxy on given host + port
--socks5 <host[:port]> SOCKS5 proxy on given host + port
--socks5-basic Username/password auth for SOCKS5 proxies
--socks5-gssapi Enable GSS-API auth for SOCKS5 proxies
--socks5-gssapi-nec Compatibility with NEC SOCKS5 server
--socks5-gssapi-service <name> SOCKS5 proxy service name for GSS-API
--socks5-hostname <host[:port]> SOCKS5 proxy, pass hostname to proxy
-Y, --speed-limit <speed> Stop transfers slower than this
-y, --speed-time <seconds> Trigger 'speed-limit' abort after this time
--ssl Try enabling TLS
--ssl-allow-beast Allow security flaw to improve interop
--ssl-auto-client-cert Use auto client certificate (Schannel)
--ssl-no-revoke Disable cert revocation checks (Schannel)
--ssl-reqd Require SSL/TLS
--ssl-revoke-best-effort Ignore missing cert CRL dist points
-2, --sslv2 SSLv2
-3, --sslv3 SSLv3
--stderr <file> Where to redirect stderr
--styled-output Enable styled output for HTTP headers
--suppress-connect-headers Suppress proxy CONNECT response headers
--tcp-fastopen Use TCP Fast Open
--tcp-nodelay Set TCP_NODELAY
-t, --telnet-option <opt=val> Set telnet option
--tftp-blksize <value> Set TFTP BLKSIZE option
--tftp-no-options Do not send any TFTP options
-z, --time-cond <time> Transfer based on a time condition
--tls-max <VERSION> Maximum allowed TLS version
--tls13-ciphers <list> TLS 1.3 cipher suites to use
--tlsauthtype <type> TLS authentication type
--tlspassword <string> TLS password
--tlsuser <name> TLS username
-1, --tlsv1 TLSv1.0 or greater
--tlsv1.0 TLSv1.0 or greater
--tlsv1.1 TLSv1.1 or greater
--tlsv1.2 TLSv1.2 or greater
--tlsv1.3 TLSv1.3 or greater
--tr-encoding Request compressed transfer encoding
--trace <file> Write a debug trace to FILE
--trace-ascii <file> Like --trace, but without hex output
--trace-config <string> Details to log in trace/verbose output
--trace-ids Transfer + connection ids in verbose output
--trace-time Add time stamps to trace/verbose output
--unix-socket <path> Connect through this Unix domain socket
-T, --upload-file <file> Transfer local FILE to destination
--url <url> URL to work with
--url-query <data> Add a URL query part
-B, --use-ascii Use ASCII/text transfer
-u, --user <user:password> Server user and password
-A, --user-agent <name> Send User-Agent <name> to server
--variable <[%]name=text/@file> Set variable
-v, --verbose Make the operation more talkative
-V, --version Show version number and quit
-w, --write-out <format> Output FORMAT after completion
--xattr Store metadata in extended file attributes

从服务器获取响应

服务器上返回的所有内容都是对请求的响应。因此,获取HTML页面与下载文件是一样的。

比如,从一个网址中获取html响应:

1
curl http://info.cern.ch/

从服务器中获取文章的列表:

1
curl https://jsonplaceholder.typicode.com/posts

我们知道了如何从服务器获取响应,那么就可以下载文件 (比如 google 的logo) :

1
curl https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png

上述命令将转储你无法在终端中查看的二进制图像数据,首先需要保存它们,然后使用照片查看器查看(国内访问google需FQ)。

注:选项在命令中的位置是没有严格顺序的,所以如果你将选项放在了最后,而例子中将其放在了开始,则不需要担心。

使用默认的文件名保存文件

互联网上的每个文件都会有一个文件名,要使用其原名称保存下载的文件,可以使用 -O 选项:

1
curl -O http://www.google.com/robots.txt

使用自定义名称保存文件

要使用自定义的名称保存文件,使用 -o 选项,后跟(严格的)自定义名称:

1
curl -o http://www.google.com/robots.txt googleRobots.txt

下载多个文件

要下载多个文件,可使用空格分开:

1
curl url1 url2 url3

如果你要对所有 url 都使用 -O 选项,可以这样:

1
curl url1 url2 url3 -O -O -O

应对任何选项都可以执行相同的方法。第一个选项针对的是第一个url,第二个选项针对第二个url,以此类推。

下载一系列文件

curl 具有从服务器下载一系列文件的功能,看下面的例子:

1
curl http://www.google.com/logo/logo[1-9].png

上面的命令下载logo1,png, logo2.png, logo3.png, 一直到 logo9.png。

只下载最新版本

仅当文件的修改时间晚于给定时间时才下载文件:

1
curl url -z "DD MMM YY MM:HH:SS"

继续下载

如果已经部分传输了文件,可以使用 -C 选项恢复传输。需要继续传输的偏移量应作为参数传递给 -C 标志。

1
curl -C 1024 http://seeni.linuxhandbook.org/files/largeFile.mpv -O

上传文件

要将文件上传到服务器,需要使用 -T 选项,后跟本地的文件路径:

1
curl -T uploadFile.txt http://upload.linuxhandbook.org/files

删除文件

要删除名为 deleteFile.txt 的文件,可以使用 -X 选项,这个选项可以用于任何 HTTP 方法 (比如 GET, POST, PUT, DELETE, PATCH)。如果没有 HTTP 方法,大多数 FTP 服务器都会配置 DELETE 方法。

1
curl -X DELETE http://upload.linuxhandbook.org/files/deleteFile.txt

你还可以修改上述命令来为任何 HTTP 方法执行相应的任务。例如,如果你的服务器允许 TRUNCATE 方法(一个创建的方法,不是标准的),只删除文件中的内容,而不删除文件本身,则可以使用类似如下命令:

1
curl -X  TRUNCATE http://upload.linuxhandbook.org/files/mysql.dump

上面提到的是 curl 的主要用途。(在使用的过程中)可能会遇到一些困难,比如重定向、用户身份校验、SSL证书等,我们称它们为附加项,因为它们是可选的,但对于某些操作来说仍然是很重要的。在下面的章节中,我们将讨论这些附加项,以及如何使用 curl 来处理这些附加项。

避免重定向

当你请求地址 http://www.google.com,你得到的可能是 www.google.co.in, 这是因为地址的重定向(状态代码在300-399范围内的HTTP数据包)。

你可以使用 -L 选项来避免重定向:

1
curl -L  http://www.google.com

身份验证

当服务器配置为仅为具有凭据的特定个人服务时,会为他们提供用户名和密码(即需要登录才能访问)。可以使用 -u 选项:

1
curl -u username:password http://seeni.linuxhandbook.org/files/tasks.txt

数据传输限制

如果要施加数据传输限制,可以使用 --limit-rate 选项。以下命令尝试将下载速率限制到10k:

1
curl --limit-rate 10K http://seeni.linuxhandbook.org/files/logoDetails.tgz

显示/隐藏传输状态

如果响应是从终端执行的,比如上传,下载,那么curl会自动显示传输的状态(进度条)。如果不想看到进度条,只需要在命令后面加上 -s 选项即可,这样在终端上就不会显示进度了。

14. 忽略 SSL 证书

还记得有些网站访问时,需要授予安全证书的情况吗?如果你信任该地址并希望进行数据传输,则可以使用 -k 选项来忽略 SSL 证书验证:

1
curl -k https://notSoSecure.org/files/logoDetails.tgz

获取信息头

在进行数据传输的时候显示信息头,可使用 -i 选项:

1
curl -i http://www.google.com/robots.txt

只显示信息头

如果只想要信息头,而不想要数据,则使用 -I 选项:

1
curl -I http://www.google.com/robots.txt

更改用户代理

一些网站或服务器不允许某些特定的设备访问系统。但是他们怎么知道我们使用什么设备呢?这是由 User-Agent HTTP 的头信息来告诉对方的。我们可以使用 -A 选项来更改 User Agent:

1
curl -A "Mozilla FireFox(42.0)" http://notAllowedForCLI.sites.org/randomFile.png

向服务器发送数据

如果服务器需要一些参数数据,比如 token 或者 API密钥,可使用 -d 选项发送数据。在命令行中,发送的数据需要跟在 -d 选项后面,可以使用 & 来组合多个数据。这通常是在浏览器中通过 GET 或 POST 请求来完成的,这是你发送表单信息的方式之一。

1
curl -d "token=34343abvfgh&name='seeni'" http://api.restful.org/getcontent

Cookie 是一些小的信息,允许在无状态的 HTTP 协议中保持会话。如果想了解更多cookie的信息,可以访问 Using HTTP cookies

要将cookie下入文件,可以使用 -c 选项,后跟 cookie 文件名:

1
curl -c googleCookie.txt http://www.google.com/files

从文件中读取Cookie

要从文件中读取 cookie, 可使用 -b 选项,后跟cookie文件名:

1
curl -b googleCookie.txt http://www.google.com/files

请注意,-b 选项仅从文件中读取 cookie,如果服务器重新发送了另一个cookie,你需要使用 -c 选项来重写它们。

启动新会话

如果想要丢弃cookie来启动一个新会话,可使用 -j 选项。使用该选项后,即便你通过 -b 读取到了cookie,它也会启动一个新的会话。

1
curl -b googleCookie.txt http://www.google.com/files -j

返回状态码

当你使用 curl 命令请求一个网页或者服务器时,服务器会返回一个 HTTP 状态码。这个状态码是一个三位数字,它表示了请求的结果。HTTP 状态码主要分为五类:

1xx (信息性状态码) - 表示接收的请求正在处理。

例子: 100 (继续)

2xx (成功状态码) - 表示请求正常处理完毕。

例子: 200 (成功), 201 (已创建), 204 (无内容)

3xx (重定向状态码) - 表示需要后续操作才能完成这一请求。

例子: 301 (永久移动), 302 (临时重定向), 304 (未修改)

4xx (请求错误状态码) - 表示请求可能出错,妨碍了服务器的处理。

例子: 400 (错误请求), 401 (未授权), 403 (禁止), 404 (未找到)

5xx (服务器错误状态码) - 表示服务器处理请求出错。

例子: 500 (内部服务器错误), 502 (错误网关), 503 (服务不可用)
在使用 curl 命令时,可以查看返回的 HTTP 状态码,这对于调试和分析网站请求很有帮助,下文是一些常见的方法来获取 curl 命令返回的状态码。

使用 -I 或 -i 选项

最简单的方法就是在 curl 命令后加上 -I-i 选项。这样可以在响应结果中看到完整的 HTTP 头信息,包括状态码。
例如:

1
curl -I https://apifox.com

这会显示类似这样的输出:

1
2
3
4
5
6
7
8
9
10
11
12
HTTP/1.1 200 OK
Server: openresty/1.21.4.1
Date: Fri, 26 Apr 2024 03:35:31 GMT
Content-Type: text/html
Content-Length: 242152
Last-Modified: Fri, 19 Apr 2024 23:08:54 GMT
Connection: keep-alive
Vary: Accept-Encoding
Set-Cookie: abflag=1714102531; domain=.apifox.com ;path=/; Expires=Tue, 19-Jan-2038 03:14:07 GMT
ETag: "6622f986-3b1e8"
Cache-Control: max-age=300
Accept-Ranges: bytes

可以看到状态码是 200 OK,表示请求成功。

使用 -o /dev/null 和 -w “%{http_code}”

如果你只想看到状态码,不需要其他信息,Linux 系统可以使用 -o /dev/null-s -w "%{http_code}" 选项:

1
curl -o /dev/null -s -w "%{http_code}" https://apifox.com

这样,curl 会将访问的网站响应结果中除状态码之外的所有输出重定向到/dev/null(即不显示),只在命令行中输出 HTTP 状态码。
Windows 使用 NUL 来提供类似的功能。所以,当你尝试在 Windows 使用类似于 UNIX 的命令时,你应该将 /dev/null 改为 NUL

1
curl -o NUL -s -w "%{http_code}" https://apifox.com

QAs

使用curl下载压缩包的时候,得到的却是一个html文件

curl 是在 Linux 命令行下载文件的一个很好用的工具。使用的方法也很简单:

1
curl -O <url_of_the_file>

上述命令使用了一个 -O 选项,会将给定的地址中的文件下载到本地,文件命名与源文件相同。

这在大多数情况下是能正常运行的,但是有时候,从 GitHub 或者 SourceForge 下载文件的时候,下载到的往往不是我们想要的文件。

比如,我要在 GitHub 上下载 tar.gz 格式的 archinstall 脚本,其位于 git 的发布页面上(地址为 https://github.com/archlinux/archinstall/releases/)。

当我在浏览器上打开这个地址的时候,我会在页面上看到位于tar.gz归档文件中的源代码;但是如果我使用 curl 命令在终端上下载同一个地址中的文件,得到的是一个很小的文件,是一个格式不正确的归档文件:

1
2
3
4
5
tar -zxvf v2.4.2.tar.gz 

gzip: stdin: not in gzip format
tar: Child returned status 1
tar: Error is not recoverable: exiting now

当我使用 file 命令来查看该文件的类型时,它告诉我这是一个html文档:

1
2
file v2.4.2.tar.gz 
v2.4.2.tar.gz: HTML document, ASCII text, with no line terminators

我原本是要下载一个 tar 包,得到的却是一个html文档,为什么呢?下面我们来看看如何解决这个问题。

使用 curl 正确下载归档文件

要下载归档文件(比如tar.gz文件),我们需要使用其他选项,以便指定的url重定向到实际的归档文件:

1
curl -JLO URL_of_the_file

上述命令用到的 -JLO 选项顺序是无序的,我们分别看一下每个选项的含义:

选项 含义
-J 此选项告诉 -O--remote-name 选项使用服务器指定的内容处理文件名,而不是从 URL 提取文件名;
-L 如果服务器报告请求的页面已经移动到其他位置(3开头的响应码),此选项将使curl重新请求新位置;
-O 使用此选项,不需要为下载指定输出的文件名。

如下图所示,我们使用 curl -JLO 选项下载后,可以得到正确的文件:

如需要登录怎么办呢?

上述命令在公共页面中是可以的。但是如果我们想要从私有库或者 GitLab 下载文件(需要登录),那么使用curl可能会看到一条关于重定向到登录页面的提示:

1
<html><body>You are being <a href="https://gitlab.com/users/sign_in">redirected</a>.</body></html>

这种情况下,需要使用 -H 选项携带 API 令牌(token)。

1
curl -H <token> -JLO <url_of_the_file>