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 对照

Linux命令Linux系统UbuntuUbuntu 22.04命令行网络工具2026/10/16

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)。

六、参考链接