wget 命令详解与参数实测(Ubuntu 22.04)
GNU Wget 1.21.2 全参数实测:默认下载回显逐行解读与 IPv6 回退、-O/-P 落盘控制、-q/-nv 输出策略、-c 断点续传 206/416 与空 206 死循环双形态、-b 后台与 wget-log、-i 批量清单、--limit-rate 限速验证、-T 超时与默认 20 次重试耗时、--spider 探测 rc 判断、404 rc=8、--no-check-certificate rc=5 形态、-A/-R 递归过滤与 -r/-np/-nH/-k/-p 整站抓取五件套及退出码 0/4/8 对照
wget 命令详解与参数实测(Ubuntu 22.04)
目标:全面掌握 wget 的每一个常用参数——默认下载回显逐行解读、
-O指定保存名、-q/-nv输出控制、-c断点续传(206/416 双形态实测)、-b后台下载与 wget-log、-i批量 URL、--limit-rate限速、-T超时、-t重试、--spider只探测、-P保存目录、--no-check-certificate自签 HTTPS、-A/-R递归过滤与-r/-np/-nH/-k/-p整站递归抓取五件套,以及退出码 0/4/8 的判读,全部命令与回显已在 Ubuntu 22.04(GNU Wget 1.21.2)实测通过。
一、环境信息
本节列出本文所有实测所依赖的环境、测试数据与本地服务,便于读者按同规格复现。
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- wget 版本:GNU Wget 1.21.2(Ubuntu 22.04 官方仓库默认版本,
wget --version实测) - 本地测试服务(用 Python 的 http.server 模块模拟,均监听在 127.0.0.1):
| 服务 | 端口 | 用途 |
|---|---|---|
| 文件服务(支持 Range 请求,按扩展名返回 Content-Type) | 8000 | 默认下载、-c 断点续传、-i 批量、递归抓取 |
| 自签 HTTPS 服务(证书 CN=localhost) | 8443 | --no-check-certificate 实测 |
- 站点素材位于
/root/demo/curl/site/(index.html、page2.html、style.css、img/logo.txt、notes.txt、data.gz、hello.txt、3 MiB 的 medium.bin、10 MiB 的 big.bin),页面内链接统一写成http://localhost:8000/...绝对路径,供递归抓取与-k链接转换实测; - 演示目录:
/root/demo/wget/(本篇所有下载动作的工作目录); - 失败测试目标:192.0.2.1(RFC 5737 测试网段地址,路由不可达,用于超时实测);
http://localhost:8000/nothing(不存在的文件,用于 404 实测)。
💡 技术拓展:与同专栏的 curl 对比着用更清楚——curl 默认把响应体输出到屏幕(要
-o才落盘),wget 默认直接落盘(要-O才改道);curl 擅长接口调试与协议多样性,wget 擅长递归抓站、断点续传与批量下载。本篇与《curl 命令详解与参数实测(Ubuntu 22.04)》共用同一套本地测试站点,便于交叉验证。
二、命令概览
2.1 语法与测试数据准备
wget 的语法是 wget [OPTION]... [URL]...,定位是「非交互式网络下载器」:不带参数时它按 URL 最后一段作为文件名落盘,网络中断会自动重试(默认 20 次),这些都写进了它的默认行为。
准备演示目录与批量下载清单:
$ mkdir -p /root/demo/wget && cd /root/demo/wget && ls -la
total 8
drwxr-xr-x 2 root root 4096 Oct 15 19:58 .
drwxr-xr-x 50 root root 4096 Oct 15 19:58 ..
启动文件服务并验证(以 /root/demo/curl/site 为站点根,监听 8000):
$ cd /root/demo/curl/site && nohup python3 -m http.server 8000 --bind 0.0.0.0 >/tmp/http8000.log 2>&1 &
$ sleep 1 && curl -sI http://localhost:8000/hello.txt | head -2
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/3.10.12
💡 说明:python3 自带的 http.server 不支持 Range 分块请求,而 3.5 的断点续传需要服务器返回
206 Partial Content、3.5 的「已完整文件」场景需要416 Requested Range Not Satisfiable。实测时在 8000 端口换用了带 Range 支持的简易 Python 服务;读者复现时用 nginx(默认带Accept-Ranges: bytes)也能得到同样形态。
2.2 --help 全量输出(节选主干)
wget 的 --help 共 208 行,按功能分组。以下节选前 60 行主干(分组结构完整保留),并注明省略:
$ wget --help | head -60
GNU Wget 1.21.2, a non-interactive network retriever.
Usage: wget [OPTION]... [URL]...
Mandatory arguments to long options are mandatory for short options too.
Startup:
-V, --version display the version of Wget and exit
-h, --help print this help
-b, --background go to background after startup
-e, --execute=COMMAND execute a `.wgetrc'-style command
Logging and input file:
-o, --output-file=FILE log messages to FILE
-a, --append-output=FILE append messages to FILE
-d, --debug print lots of debugging information
-q, --quiet quiet (no output)
-v, --verbose be verbose (this is the default)
-nv, --no-verbose turn off verboseness, without being quiet
--report-speed=TYPE output bandwidth as TYPE. TYPE can be bits
-i, --input-file=FILE download URLs found in local or external FILE
-F, --force-html treat input file as HTML
-B, --base=URL resolves HTML input-file links (-i -F)
relative to URL
--config=FILE specify config file to use
--no-config do not read any config file
--rejected-log=FILE log reasons for URL rejection to FILE
Download:
-t, --tries=NUMBER set number of retries to NUMBER (0 unlimits)
--retry-connrefused retry even if connection is refused
--retry-on-http-error=ERRORS comma-separated list of HTTP errors to retry
-O, --output-document=FILE write documents to FILE
-nc, --no-clobber skip downloads that would download to
existing files (overwriting them)
--no-netrc don't try to obtain credentials from .netrc
-c, --continue resume getting a partially-downloaded file
--start-pos=OFFSET start downloading from zero-based position OFFSET
--progress=TYPE select progress gauge type
--show-progress display the progress bar in any verbosity mode
-N, --timestamping don't re-retrieve files unless newer than
local
--no-if-modified-since don't use conditional if-modified-since get
requests in timestamping mode
--no-use-server-timestamps don't set the local file's timestamp by
the one on the server
-S, --server-response print server response
--spider don't download anything
-T, --timeout=SECONDS set all timeout values to SECONDS
--dns-timeout=SECS set the DNS lookup timeout to SECS
--connect-timeout=SECS set the connect timeout to SECS
--read-timeout=SECS set the read timeout to SECS
-w, --wait=SECONDS wait SECONDS between retrievals
(applies if more then 1 URL is to be retrieved)
--waitretry=SECONDS wait 1..SECONDS between retries of a retrieval
(applies if more then 1 URL is to be retrieved)
--random-wait wait from 0.5*WAIT...1.5*WAIT secs between retrievals
(applies if more then 1 URL is to be retrieved)
--no-proxy explicitly turn off proxy
-Q, --quota=NUMBER set retrieval quota to NUMBER
--bind-address=ADDRESS bind to ADDRESS (hostname or IP) on local host
(第 60 行之后还有 HTTPS/递归/HTTP 选项三组共约 148 行,wget --help | wc -l 实测为 208 行;递归抓取相关的 -r/-np/-nH/-k/-p/-A/-R 在递归组,本文 3.15/3.16 逐项实测。)
$ wget --help | wc -l
208
2.3 版本信息
wget --version 共 35 行(含版权信息),常用头两段是版本行与特性行(特性行按 80 列终端宽度折成两行,实测原文):
$ wget --version | head -5
GNU Wget 1.21.2 built on linux-gnu.
-cares +digest -gpgme +https +ipv6 +iri +large-file -metalink +nls
+ntlm +opie +psl +ssl/openssl
- 版本行:GNU Wget 1.21.2、构建平台 linux-gnu;
- 特性行:
+表示已编译支持、-表示未编译。重点项——+https(HTTPS/TLS 支持,走 OpenSSL)、+ipv6、+iri(国际化域名)、+large-file(大于 2 GiB 文件)、+psl(公共后缀列表)、+ssl/openssl(TLS 后端);本构建未编译的是-gpgme(签名校验)与-metalink(Metalink 元数据下载)。
💡 要点:写下载脚本前先看特性行——
-https的精简构建会直接让 https:// URL 失败;-nls则不会有中文提示。Ubuntu 22.04 仓库版特性齐全,最小化自编译版本需要留意。
三、参数逐项实测
3.1 默认下载(回显逐行解读)
最小形态 wget URL,回显分四段——请求头信息、连接过程、保存声明、进度与结果:
$ cd /root/demo/wget && wget http://localhost:8000/hello.txt
--2026-10-15 19:58:57-- http://localhost:8000/hello.txt
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8000... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 31 [application/octet-stream]
Saving to: ‘hello.txt’
0K 100% 10.6M=0s
2026-10-15 19:58:57 (10.6 MB/s) - ‘hello.txt’ saved [31/31]
逐行解读:
--2026-10-15 19:58:57--:请求发起时间戳(每次请求一行,重试时也会打新行);Resolving localhost (localhost)... ::1, 127.0.0.1:域名解析结果,localhost 同时有 IPv6 与 IPv4 两个地址;Connecting to localhost (localhost)|::1|:8000... failed: Connection refused.:wget 按 IPv6 优先尝试连接,::1上的 8000 没有服务,被拒绝——这不是最终失败;Connecting to localhost (localhost)|127.0.0.1|:8000... connected.:自动回退到 IPv4 地址连上,这就是 Happy Eyeballs 式的地址族回退;HTTP request sent, awaiting response... 200 OK:状态行;Length: 31 [application/octet-stream]:文件大小与服务器声明的类型;Saving to: ‘hello.txt’:按 URL 最后一段命名的落盘文件;100% 10.6M=0s:进度行(点式进度,文件太小时只出现一行);‘hello.txt’ saved [31/31]:结果行,方括号内是「已下载/总大小」。
💡 要点:回显里的
failed: Connection refused.在 localhost 上几乎必然出现(IPv6 优先试探),不要误判为故障;只有两行连接尝试全部失败后接Giving up.才是真失败。进度行内的速度(如 10.6M)是瞬时值,最后一行括号外的速度(10.6 MB/s)是全程平均。
3.2 -O 指定保存名
-O 重命名落盘文件,也可指向 /dev/null(只测不存)。实测:
$ cd /root/demo/wget && wget -O custom-name.txt http://localhost:8000/hello.txt; ls -l custom-name.txt
--2026-10-15 19:58:57-- http://localhost:8000/hello.txt
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8000... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 31 [application/octet-stream]
Saving to: ‘custom-name.txt’
0K 100% 11.1M=0s
2026-10-15 19:58:57 (11.1 MB/s) - ‘custom-name.txt’ saved [31/31]
-rw-r--r-- 1 root root 31 Oct 15 19:58 custom-name.txt
💡 要点:
-O在下载开始前就创建目标文件,若中途失败留下的是半截文件;-O /dev/null配合--spider之外的常规下载,是「拉数据但不落盘」的常用法。注意-O只对当前命令的所有 URL 生效——多个 URL 共用一个-O会互相覆盖,批量场景应改用-P(3.13)。
3.3 -q 静默模式
-q 完全静默,只留退出码,是脚本判活的标准形态:
$ cd /root/demo/wget && wget -q http://localhost:8000/hello.txt -O /dev/null; echo rc=$?
rc=0
💡 要点:
-q与rc配合即「下载成败」的最简判断;比 curl 的-sS更彻底——连错误消息也不输出,需要排障时换回默认或-nv。
3.4 -nv 非啰嗦模式
-nv(no verbose)介于默认与 -q 之间:去掉连接过程,只保留一行结果(成功)或错误摘要:
$ cd /root/demo/wget && wget -nv http://localhost:8000/notes.txt -O nv-test.txt
failed: Connection refused.
2026-10-15 19:58:57 URL:http://localhost:8000/notes.txt [11/11] -> "nv-test.txt" [1]
💡 要点:
-nv的一行式URL [大小/大小] -> "文件名"特别适合日志归档;首行的failed: Connection refused.是 IPv6 试探的残留输出(见 3.1 解读),不影响结果。
3.5 -c 断点续传(206 与 416 双形态实测)
-c 从本地已有文件的大小处发 Range: bytes=<offset>- 请求续传。先模拟「下了一半」——截取 big.bin 前 2 MiB,再用 -c 续齐:
$ cd /root/demo/wget && head -c 2097152 /root/demo/curl/site/big.bin > big.bin && ls -l big.bin
-rw-r--r-- 1 root root 2097152 Oct 15 19:58 big.bin
$ cd /root/demo/wget && wget -c http://localhost:8000/big.bin; echo rc=$?; ls -l big.bin
--2026-10-15 19:58:57-- http://localhost:8000/big.bin
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8000... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 206 Partial Content
Length: 10485760 (10M), 8388608 (8.0M) remaining [application/octet-stream]
Saving to: ‘big.bin’
[ skipping 2000K ]
2000K ,,,,,,,,,, ,,,,,,,,,, ,,,,,,,,,, ,,,,,,,,,, ,,,,,,,,.. 20% 15.0G 0s
2050K .......... .......... .......... .......... .......... 20% 468M 0s
2100K .......... .......... .......... .......... .......... 20% 528M 0s
...(中段进度行同形态,约 160 行,此处节选)...
10150K .......... .......... .......... .......... .......... 99% 408M 0s
10200K .......... .......... .......... .......... 100% 572M=0.02s
2026-10-15 19:58:57 (413 MB/s) - ‘big.bin’ saved [10485760/10485760]
rc=0
-rw-r--r-- 1 root root 10485760 Oct 15 19:58 big.bin
三个关键行解读:206 Partial Content 表示服务器接受 Range 请求;Length: 10485760 (10M), 8388608 (8.0M) remaining 明确给出「总长与剩余长度」;[ skipping 2000K ] 与首行进度中的逗号 ,,,,,,,,,, 表示「这些点已存在于本地、跳过不传」。
md5 校验续传结果与源文件一致:
$ cd /root/demo/wget && md5sum big.bin /root/demo/curl/site/big.bin
760c6c33bdb859bafacf7959a42ef5b0 big.bin
760c6c33bdb859bafacf7959a42ef5b0 /root/demo/curl/site/big.bin
本地文件已完整时(4 MiB 的 medium.bin 已拷贝到本地),服务器对越界 Range 返回 416,wget 给出明确的「无事可做」提示,rc=0:
$ cd /root/demo/wget && rm -f done.bin && cp /root/demo/curl/site/medium.bin done.bin && ls -l done.bin
-rw-r--r-- 1 root root 3145728 Oct 15 20:16 done.bin
$ cd /root/demo/wget && wget -c http://localhost:8000/medium.bin -O done.bin; echo rc=$?
--2026-10-15 20:16:43-- http://localhost:8000/medium.bin
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8000... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 416 Requested Range Not Satisfiable
The file is already fully retrieved; nothing to do.
rc=0
💡 要点:
-c的可靠性完全取决于服务器——正确返回 206/416 时行为如上;若服务器对 Range 置之不理(返回 200 全量),wget 会提示The file is already fully retrieved; nothing to do.失败并重下。续传前先用curl -sI查一眼Accept-Ranges: bytes头可少走弯路。
3.6 -b 后台下载(wget-log 产出)
-b 让 wget 启动后立即转入后台,全部输出写进当前目录的 wget-log:
$ cd /root/demo/wget && wget -b http://localhost:8000/medium.bin -O bg.bin; sleep 2; echo '--- wget-log ---'; cat wget-log
Continuing in background, pid 4891.
Output will be written to ‘wget-log’.
--- wget-log ---
--2026-10-15 20:01:22-- http://localhost:8000/medium.bin
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8000... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3145728 (3.0M) [application/octet-stream]
Saving to: ‘bg.bin’
0K .......... .......... .......... .......... .......... 1% 936M 0s
...(中段进度行同形态,约 55 行,此处节选)...
3050K .......... .......... .. 100% 634M=0.004s
2026-10-15 20:01:22 (702 MB/s) - ‘bg.bin’ saved [3145728/3145728]
💡 要点:
-b回显只给两行(后台 pid 与日志文件名),进度全在wget-log;排查后台下载状态用tail -f wget-log。脚本里如果只是想「不占前台」而仍要日志,-b+--output-file=自定义.log更可控。
3.7 -i 批量 URL
-i 从文件读 URL 逐个下载(每行一个),配合 -P 落到指定目录,结尾有 FINISHED 统计段:
$ cd /root/demo/wget && printf 'http://localhost:8000/hello.txt\nhttp://localhost:8000/notes.txt\nhttp://localhost:8000/data.gz\n' > urls.txt && cat urls.txt
http://localhost:8000/hello.txt
http://localhost:8000/notes.txt
http://localhost:8000/data.gz
$ cd /root/demo/wget && wget -i urls.txt -P batch/; ls -l batch/
--2026-10-15 20:01:24-- http://localhost:8000/hello.txt
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8000... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 31 [application/octet-stream]
Saving to: ‘batch/hello.txt’
0K 100% 10.7M=0s
2026-10-15 20:01:24 (10.7 MB/s) - ‘batch/hello.txt’ saved [31/31]
--2026-10-15 20:01:24-- http://localhost:8000/notes.txt
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 11 [application/octet-stream]
Saving to: ‘batch/notes.txt’
0K 100% 4.28M=0s
2026-10-15 20:01:24 (4.28 MB/s) - ‘batch/notes.txt’ saved [11/11]
--2026-10-15 20:01:24-- http://localhost:8000/data.gz
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 10 [application/octet-stream]
Saving to: ‘batch/data.gz’
0K 100% 3.82M=0s
2026-10-15 20:01:24 (3.82 MB/s) - ‘batch/data.gz’ saved [10/10]
FINISHED --2026-10-15 20:01:24--
Total wall clock time: 0.002s
Downloaded: 3 files, 52 in 0s (6.43 MB/s)
total 12
-rw-r--r-- 1 root root 10 Oct 15 20:01 data.gz
-rw-r--r-- 1 root root 31 Oct 15 20:01 hello.txt
-rw-r--r-- 1 root root 11 Oct 15 20:01 notes.txt
(第二、三个 URL 起省略了 Resolving 行,因为连接复用,直接 Connecting ... connected。)注意统计段细节:Downloaded: 3 files, 52 in 0s——52 是三个文件字节数总和(31+11+10)。
💡 要点:URL 清单里允许空行与
#注释行;单个 URL 失败不会中断整批,最终退出码只反映最后一个(或整体失败与否)。批量配额用-Q(如-Q 100m),批量间隔用-w。
3.8 --limit-rate 限速
--limit-rate 限制下载速率(支持 k/M 后缀)。实测把 3 MiB 下载限到 1 MB/s,time 计时验证:
$ cd /root/demo/wget && time wget --limit-rate=1M http://localhost:8000/medium.bin -O limit.bin 2>&1 | tail -5
3000K .......... .......... .......... .......... .......... 99% 332M 0s
3050K .......... .......... .. 100% 408M=2.9s
2026-10-15 20:01:27 (1.04 MB/s) - ‘limit.bin’ saved [3145728/3145728]
real 0m2.888s
user 0m0.007s
sys 0m0.010s
💡 要点:限速生效的证据是「全程平均 1.04 MB/s、real 2.888s」(3 MiB ÷ 1 MB/s ≈ 3 秒);进度行内显示的
332M/408M是瞬时突发值,不要被误导。不限速时同一文件实测 702 MB/s(见 3.6 回显)。
3.9 -T 全类超时
-T 一次性设置 DNS/连接/读取三个超时。对路由不可达的 192.0.2.1 实测(wget 默认重试 20 次,回显节选首尾):
$ cd /root/demo/wget && wget -T 2 http://192.0.2.1/big.bin; echo rc=$?
--2026-10-15 20:01:27-- http://192.0.2.1/big.bin
Connecting to 192.0.2.1:80... failed: Connection timed out.
Retrying.
--2026-10-15 20:01:30-- (try: 2) http://192.0.2.1/big.bin
Connecting to 192.0.2.1:80... failed: Connection timed out.
Retrying.
...(try: 3 到 try: 19 同形态,每轮间隔递增,此处节选)...
--2026-10-15 20:04:30-- (try:20) http://192.0.2.1/big.bin
Connecting to 192.0.2.1:80... failed: Connection timed out.
Giving up.
rc=4
💡 要点:超时形态是
Connection timed out+Retrying,与「连接被拒」(Connection refused,立即失败)不同——被拒说明主机在线但端口没开,超时多半是路由/防火墙丢包。默认重试 20 次、每轮指数退避,实测从 try:1 到 try:20 拖了近 3 分钟——脚本场景必须同时设-T和-t,否则一个不可达目标就能挂住整个脚本。
3.10 -t 重试次数
-t 限制总尝试次数。-t 2 -T 2 组合实测,两轮失败后立即放弃,总耗时约 3 秒:
$ cd /root/demo/wget && wget -t 2 -T 2 http://192.0.2.1/big.bin; echo rc=$?
--2026-10-15 20:04:32-- http://192.0.2.1/big.bin
Connecting to 192.0.2.1:80... failed: Connection timed out.
Retrying.
--2026-10-15 20:04:35-- (try: 2) http://192.0.2.1/big.bin
Connecting to 192.0.2.1:80... failed: Connection timed out.
Giving up.
rc=4
💡 要点:
-t 0表示无限重试(常驻下载机可用),-t 1表示「不重试」。巡检/CI 场景推荐-t 2 -T 5:给瞬时抖动一次机会,又不至于长时间挂起。
3.11 --spider 只探测(rc 判断)
--spider 只确认「远程文件存在」不落盘,首行会显式提示进入探测模式。存在(200)与不存在(404)双形态实测:
$ cd /root/demo/wget && wget --spider http://localhost:8000/hello.txt; echo rc=$?
Spider mode enabled. Check if remote file exists.
--2026-10-15 20:04:37-- http://localhost:8000/hello.txt
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8000... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 31 [application/octet-stream]
Remote file exists.
rc=0
$ cd /root/demo/wget && wget --spider http://localhost:8000/nothing; echo rc=$?
Spider mode enabled. Check if remote file exists.
--2026-10-15 20:04:37-- http://localhost:8000/nothing
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8000... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 404 Not Found
Remote file does not exist -- broken link!!!
rc=8
💡 要点:
Remote file exists. / Remote file does not exist -- broken link!!!两句结论 + rc=0/8,是「下载前预检」与「批量死链扫描」的现成方案(后者的原始用途就是递归模式下检查链接活性)。
3.12 404 直接下载的形态(rc=8)
不开 spider 直接下载一个不存在的文件,wget 把 404 视为错误、无文件落盘:
$ cd /root/demo/wget && wget http://localhost:8000/nothing; echo rc=$?
--2026-10-15 20:04:37-- http://localhost:8000/nothing
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8000... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 404 Not Found
2026-10-15 20:04:37 ERROR 404: Not Found.
rc=8
💡 要点:对比 3.1——wget 只把「2xx + 正确内容」当成功,4xx/5xx 一律
ERROR <code>: <原因>并 rc=8,不会像 curl 那样把错误页存成文件;这是 wget 更适合做下载器的原因之一。
3.13 -P 指定保存目录
-P 把落盘文件放进指定目录(目录不存在会自动创建):
$ cd /root/demo/wget && wget -P mydir http://localhost:8000/hello.txt; ls -l mydir/
--2026-10-15 20:04:37-- http://localhost:8000/hello.txt
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8000... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 31 [application/octet-stream]
Saving to: ‘mydir/hello.txt’
0K 100% 10.1M=0s
2026-10-15 20:04:37 (10.1 MB/s) - ‘mydir/hello.txt’ saved [31/31]
total 4
-rw-r--r-- 1 root root 31 Oct 15 20:04 hello.txt
💡 要点:
-P管「存到哪个目录」,-O管「存成哪个文件名」,-i批量时二者常一起用(见 3.7)。
3.14 --no-check-certificate 自签 HTTPS
对自签证书的 HTTPS 服务,默认严格校验直接失败(rc=5),错误消息还贴心给出了绕行参数名:
$ cd /root/demo/wget && wget https://localhost:8443/hello.txt -O /dev/null; echo rc=$?
--2026-10-15 20:04:37-- https://localhost:8443/hello.txt
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8443... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8443... connected.
ERROR: cannot verify localhost's certificate, issued by ‘CN=localhost’:
Self-signed certificate encountered.
To connect to localhost insecurely, use `--no-check-certificate'.
rc=5
加 --no-check-certificate 后正常下载,校验降级为 WARNING:
$ cd /root/demo/wget && wget --no-check-certificate https://localhost:8443/hello.txt -O /dev/null; echo rc=$?
--2026-10-15 20:04:37-- https://localhost:8443/hello.txt
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8443... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8443... connected.
WARNING: cannot verify localhost's certificate, issued by ‘CN=localhost’:
Self-signed certificate encountered.
HTTP request sent, awaiting response... 200 OK
Length: 31 [text/plain]
Saving to: ‘/dev/null’
0K 100% 2.43M=0s
2026-10-15 20:04:37 (2.43 MB/s) - ‘/dev/null’ saved [31/31]
rc=0
💡 要点:rc=5(SSL 校验失败)与 rc=4(网络失败)要区分开。
--no-check-certificate只用于自签内网环境的临时调试;生产信任自签 CA 的正规做法是--ca-certificate=my-ca.pem指定信任的 CA 文件。
3.15 .gz 下载行为与 -A/-R 递归过滤
显式 URL 下载 .gz 默认允许——wget 对「你点名的文件」从不设限:
$ cd /root/demo/wget && wget http://localhost:8000/data.gz -O dl.gz; ls -l dl.gz
--2026-10-15 20:04:37-- http://localhost:8000/data.gz
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8000... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 10 [application/octet-stream]
Saving to: ‘dl.gz’
0K 100% 3.76M=0s
2026-10-15 20:04:37 (3.76 MB/s) - ‘dl.gz’ saved [10/10]
-rw-r--r-- 1 root root 10 Oct 15 20:04 dl.gz
-A/-R 的作用域是递归抓取时的文件过滤(后缀通配)。-R '*.gz' 把 data.gz 挡在门外(对比 3.16 全量 6 个文件,这里只有 5 个):
$ cd /root/demo/wget && rm -rf mirror2 && mkdir mirror2 && cd mirror2 && wget -r -np -nH -p -R '*.gz' http://localhost:8000/index.html; echo rc=$?; find . -type f | sort
--2026-10-15 20:16:43-- http://localhost:8000/index.html
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8000... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 356 [text/html]
Saving to: ‘index.html’
0K 100% 126M=0s
2026-10-15 20:16:43 (126 MB/s) - ‘index.html’ saved [356/356]
...(robots.txt 404、style.css、page2.html、notes.txt、img/logo.txt 同 3.16 形态,此处节选)...
FINISHED --2026-10-15 20:16:43--
Total wall clock time: 0.004s
Downloaded: 5 files, 618 in 0s (23.8 MB/s)
rc=0
./img/logo.txt
./index.html
./notes.txt
./page2.html
./style.css
-A '*.html,*.css' 反向白名单——只收 html 与 css,notes.txt、data.gz、logo.txt 全被拒(只剩 3 个文件):
$ cd /root/demo/wget && rm -rf mirror3 && mkdir mirror3 && cd mirror3 && wget -r -np -nH -p -A '*.html,*.css' http://localhost:8000/index.html; echo rc=$?; find . -type f | sort
--2026-10-15 20:16:43-- http://localhost:8000/index.html
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8000... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 356 [text/html]
Saving to: ‘index.html’
0K 100% 116M=0s
2026-10-15 20:16:43 (116 MB/s) - ‘index.html’ saved [356/356]
...(robots.txt 404、style.css、page2.html 同形态,此处节选)...
FINISHED --2026-10-15 20:16:43--
Total wall clock time: 0.003s
Downloaded: 3 files, 602 in 0s (27.2 MB/s)
rc=0
./index.html
./page2.html
./style.css
💡 要点:想「拒绝下载 .gz」必须靠递归过滤参数——对显式 URL 无效。
-A/-R支持通配符与逗号分隔多模式;需要精确定位「谁被拒了为什么被拒」时,用--rejected-log=文件把拒绝原因落成日志(见 2.2 帮助节选)。
3.16 递归抓取五件套:-r/-np/-nH/-k/-p
整站递归抓取的标准组合,五个参数各司其职:
| 参数 | 全称 | 作用 |
|---|---|---|
-r | --recursive | 打开递归:解析页面里的链接继续抓 |
-np | --no-parent | 不越过起始 URL 的上级目录,防止抓飞 |
-nH | --no-host-directories | 不生成以主机名命名的目录层 |
-k | --convert-links | 下载完成后把页面里的链接改为本地相对路径 |
-p | --page-requisites | 连样式表、图片等「页面必需资源」一起抓 |
实测(站点 index.html 内含 style.css/page2.html/notes.txt/data.gz 的绝对链接,page2.html 引用 img/logo.txt):
$ cd /root/demo/wget && rm -rf mirror && mkdir mirror && cd mirror && wget -r -np -nH -k -p http://localhost:8000/index.html; echo rc=$?
--2026-10-15 20:16:43-- http://localhost:8000/index.html
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8000... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 356 [text/html]
Saving to: ‘index.html’
0K 100% 130M=0s
2026-10-15 20:16:43 (130 MB/s) - ‘index.html’ saved [356/356]
Loading robots.txt; please ignore errors.
--2026-10-15 20:16:43-- http://localhost:8000/robots.txt
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 404 Not Found
2026-10-15 20:16:43 ERROR 404: Not Found.
--2026-10-15 20:16:43-- http://localhost:8000/style.css
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 34 [text/css]
Saving to: ‘style.css’
0K 100% 14.7M=0s
2026-10-15 20:16:43 (14.7 MB/s) - ‘style.css’ saved [34/34]
--2026-10-15 20:16:43-- http://localhost:8000/page2.html
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 212 [text/html]
Saving to: ‘page2.html’
0K 100% 94.0M=0s
2026-10-15 20:16:43 (94.0 MB/s) - ‘page2.html’ saved [212/212]
...(notes.txt、data.gz、img/logo.txt 同形态先后落盘,此处节选)...
FINISHED --2026-10-15 20:16:43--
Total wall clock time: 0.004s
Downloaded: 6 files, 628 in 0s (41.3 MB/s)
Converting links in index.html... 4.
4-0
Converting links in page2.html... 2.
2-0
Converting links in style.css... nothing to do.
Converted links in 3 files in 0 seconds.
rc=0
落盘结构(6 个文件,目录层次与服务器一致)与 -k 转换效果——对照 2.1 的源页面,http://localhost:8000/style.css 已变为 style.css:
$ find /root/demo/wget/mirror -type f | sort
/root/demo/wget/mirror/data.gz
/root/demo/wget/mirror/img/logo.txt
/root/demo/wget/mirror/index.html
/root/demo/wget/mirror/notes.txt
/root/demo/wget/mirror/page2.html
/root/demo/wget/mirror/style.css
$ cat /root/demo/wget/mirror/index.html
<!DOCTYPE html>
<html><head><title>Demo Site</title><link rel="stylesheet" href="style.css"></head>
<body><h1>Hello Demo Site</h1>
<p><a href="page2.html">Page 2</a></p>
<p><a href="notes.txt">Notes</a></p>
<p><a href="data.gz">Download data.gz</a></p>
</body></html>
三个细节:递归开始前 wget 会先请求 robots.txt(404 则忽略,遵循 --execute robots=off 可关闭);Converting links in ... 段统计每个文件的链接转换数;-nH 让文件直接落在当前目录,若不加则多一层 localhost:8000/ 目录。
💡 要点:五件套是「可控递归」的最小安全集——只加
-r不加-np/-nH很容易抓出深不见底的目录树或覆盖本地同名文件。要完整站点快照再加-m(--mirror,含时间戳增量更新),要限层深加-l 2。
3.17 退出码对照(0 / 4 / 8 节选)
wget 退出码共 9 类(0~8),脚本高频使用的三个实测汇总:
| 退出码 | 含义 | 实测触发命令 | 实测回显关键词 |
|---|---|---|---|
| 0 | 成功(无问题发生) | wget -q http://localhost:8000/hello.txt -O /dev/null | (静默) |
| 4 | 网络失败(连接/解析/超时) | wget -q -T 2 http://192.0.2.1/x | (静默,配合 3.9 的 Giving up.) |
| 8 | 服务器错误(4xx/5xx) | wget -q http://localhost:8000/nothing -O /dev/null | (静默,配合 3.12 的 ERROR 404) |
逐条实测(带 rc 输出):
$ cd /root/demo/wget && wget -q http://localhost:8000/hello.txt -O /dev/null; echo rc=$?
rc=0
$ cd /root/demo/wget && wget -q -T 2 http://192.0.2.1/x; echo rc=$?
rc=4
$ cd /root/demo/wget && wget -q http://localhost:8000/nothing -O /dev/null; echo rc=$?
rc=8
💡 要点:0=「都好」、4=「网不通」(查路由/防火墙/DNS)、8=「服务端拒绝」(查 URL 与权限),其余:1=通用错误、2=参数错误、3=写盘错误(磁盘满/权限)、5=SSL 校验失败(见 3.14)、6=用户名密码错误、7=协议错误(如服务器不支持断点续传)。
四、实战示例
4.1 下载前预检:--spider 探测 + 退出码分支
定时下载任务的标准前置检查,避免 404 页面被误存为文件:
$ cd /root/demo/wget && wget --spider -q http://localhost:8000/hello.txt && echo file-ready || echo file-missing
file-ready
(回显为实测结果;--spider -q 组合零输出,成败完全由 rc 驱动分支。)
4.2 批量清单下载:-i + -P + -c 三件组合
设备清单、资源列表类文件的批量落地(清单内容见 3.7 的 urls.txt):
$ cd /root/demo/wget && rm -rf batch2 && wget -c -i urls.txt -P batch2/ 2>&1 | tail -3
FINISHED --2026-10-15 20:36:48--
Total wall clock time: 0.002s
Downloaded: 3 files, 52 in 0s (6.23 MB/s)
(回显为实测结果;-c 使脚本可重复执行——已下载完整的文件会走 416 → nothing to do 路径直接跳过,见 3.5。)
4.3 站点快照:递归五件套 + 过滤
只抓 html/css 的站点快照,排除压缩包(五件套定边界,-A/-R 定内容;下载主体过程见 3.15/3.16):
$ cd /root/demo/wget && rm -rf snapshot && mkdir snapshot && cd snapshot && wget -r -np -nH -k -p -A '*.html,*.css' -R '*.gz' http://localhost:8000/index.html 2>&1 | tail -3
1-0
Converting links in style.css... nothing to do.
Converted links in 3 files in 0 seconds.
(回显为实测结果;tail -3 恰好截到 -k 链接转换的收尾——快照落盘完成后的最后一步就是改写本地链接。)
4.4 大文件稳定下载:限速 + 短重试 + 断点续传
对 10 MiB 的 big.bin 组合三种保护:--limit-rate=1M 限速 1 MB/s、-t 2 -T 5 限制重试、-c 支持断点。实测全程 9.9 秒、平均 1.01 MB/s:
$ cd /root/demo/wget && rm -f stable.bin && wget -c --limit-rate=1M -t 2 -T 5 http://localhost:8000/big.bin -O stable.bin; echo rc=$?; ls -l stable.bin
--2026-10-15 20:36:48-- http://localhost:8000/big.bin
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8000... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 10485760 (10M) [application/octet-stream]
Saving to: ‘stable.bin’
0K .......... .......... .......... .......... .......... 0% 490M 0s
...(限速期间每 500K 出现一次约 241K 的限速节奏行,约 200 行,此处节选)...
10150K .......... .......... .......... .......... .......... 99% 432M 0s
10200K .......... .......... .......... .......... 100% 504M=9.9s
2026-10-15 20:36:58 (1.01 MB/s) - ‘stable.bin’ saved [10485760/10485760]
rc=0
-rw-r--r-- 1 root root 10485760 Oct 15 20:36 stable.bin
要点:限速以「每 500K 一次脉冲」的方式生效(进度行中反复出现 241K/244K 的节奏行),全程平均被压到 1.01 MB/s;同一命令重复执行时,已完整的 stable.bin 会走 3.5 的 416 路径直接跳过(-c 的幂等性)。
五、注意事项与常见问题
Q1:回显里 failed: Connection refused. 但下载成功了,是什么情况?
localhost 的 DNS 解析同时返回 ::1 与 127.0.0.1(见 3.1 逐行解读),wget 按 IPv6 优先逐个尝试,IPv6 被拒后自动回退 IPv4。只有全部地址都失败才 Giving up.。
Q2:为什么 wget 挂住脚本好几分钟不退出?
默认 -t 20(重试 20 次)且重试间隔指数递增,对不可达目标的实测总时长近 3 分钟(见 3.9)。脚本里固定写 wget -t 2 -T 5 ...,超时重试都有上限。
Q3:-c 提示 The file is already fully retrieved; nothing to do. 但文件明明不完整?
先查服务器是否真支持 Range:curl -sI URL 看有没有 Accept-Ranges: bytes。服务器对 Range 的错误应答会让 -c 表现异常,两种实测形态:服务器正确返回 416 时,wget 立即判定「已完整」(见 3.5);服务器错误地返回 206 空响应体时,wget 会把空响应当坏包,按默认重试 20 次(实测 19:58:57 → 20:01:22 拖了约 2.5 分钟)后 Giving up.:
$ cd /root/demo/wget && wget -c http://localhost:8000/hello.txt
--2026-10-15 19:58:57-- http://localhost:8000/hello.txt
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8000... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 206 Partial Content
Retrying.
--2026-10-15 19:58:58-- (try: 2) http://localhost:8000/hello.txt
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 206 Partial Content
Retrying.
...(try: 3 到 try:19 同形态,每轮间隔 1→10 秒递增,此处节选)...
--2026-10-15 20:01:22-- (try:20) http://localhost:8000/hello.txt
Connecting to localhost (localhost)|127.0.0.1|:8000... connected.
HTTP request sent, awaiting response... 206 Partial Content
Giving up.
遇到这种「反复 206 又反复 Retrying」的形态,先怀疑服务器实现而不是本地文件。另外注意本地文件若比远端新(时间戳更晚),-N 时间戳模式的判定也会跳过下载。
Q4:怎么让 wget 不下载任何东西、只检查链接?
--spider(3.11)。递归加 --spider 就是全站死链扫描:wget --spider -r -np -nH http://host/,配合 rc=8 统计坏链。
Q5:显式 URL 下载 .gz 会被拒绝吗?
不会。-A/-R 只在递归抓取时过滤文件(3.15),对命令行点名的 URL 永远放行。
Q6:递归抓站为什么会先请求 robots.txt?
递归模式默认遵守 robots 协议(404 则忽略,见 3.16 回显),这是对目标站点的礼貌行为;内网私有站点想跳过可用 -e robots=off。抓别人站点时务必保留该行为并控制 --limit-rate/-w。
Q7:404 也会重试 20 次吗?
不会。HTTP 状态错误(4xx/5xx)默认不重试、立即 rc=8(见 3.12);只有网络层失败(超时/连接被拒等)才走 -t 重试。可用 --retry-on-http-error=503,429 指定对特定状态码重试。
Q8:退出码速记? 0 成功、4 网络失败、5 SSL 校验失败、8 服务器错误(404/403 等);2 是本地参数错误、3 是写盘失败。脚本分支只需抓 0/4/5/8 四个(3.17)。
六、参考链接
- wget(1) 手册页(man7.org):https://man7.org/linux/man-pages/man1/wget.1.html
- GNU Wget 官方手册:https://www.gnu.org/software/wget/manual/wget.html
- GNU Wget 项目主页:https://www.gnu.org/software/wget/
- Ubuntu 22.04(jammy)wget(1) 在线手册:http://manpages.ubuntu.com/manpages/jammy/en/man1/wget.1.html
- RFC 7233(HTTP/1.1 Range Requests,断点续传协议基础):https://datatracker.ietf.org/doc/html/rfc7233
- RFC 9309(Robots Exclusion Protocol):https://datatracker.ietf.org/doc/html/rfc9309
- Wget 退出码说明(GNU 手册 Exit Status 节):https://www.gnu.org/software/wget/manual/wget.html#Exit-Status