如果你问一个 Linux 运维“用什么工具下载文件”,得到的最常见答案不是 curl,而是 wget。这不是因为 wget 比 curl 好,而是因为 wget 的设计哲学更贴近运维场景:它不弹窗口、不打印花哨的进度条、不需要任何交互,它就是安静地、可靠地把一个 URL 列表里的所有文件拉下来,然后退出。这种“沉默老友”的特质让它在服务器脚本、Cron 任务、CI/CD 流水线里被使用了几十年。

从 1996 年至今的极简主义

wget 的全称是“GNU Wget”,最初由克罗地亚程序员 Hrvoje Nikšić 在 1996 年写成。它的名字是“World Wide Web”和“get”的组合,意思就是“从 Web 上获取东西”。这个直白的命名反映了它整个项目的气质——没有花哨概念,没有生态布局,就是解决一件事:把文件从服务器拉到本地。

截至 2024 年 11 月,wget 的最新稳定版是 1.25.0。这 28 年里,wget 增加的功能屈指可数:多协议支持、断点续传、递归下载、镜像整站、限速、后台运行、Cookie 处理。这些功能每一条都对应一个真实的服务器运维场景,没有一个是“为了看起来更现代”而加的。

递归下载:一个被严重低估的能力

wget 最让非运维人员震惊的能力是递归下载。给定一个 URL 和一些规则,它可以从这个 URL 开始,按 HTML 链接一层一层爬下去,把整站或者某个目录的所有文件都下载到本地。一个简单的命令:

wget -r -np -k https://example.com/docs/

就能把 example.com/docs/ 目录下的所有 HTML、图片、PDF 完整保存到本地,并把所有链接改成相对路径,让你可以离线浏览整个文档站点。这套能力在写爬虫、写文档归档、备份资料、做镜像站的时代,是 wget 的杀手锏。

wget 不是下载最快的工具,也不是协议支持最全的工具,但它是“最值得信任的工具”——在没有任何 GUI、没有任何监控的服务器后台,你能放心让它跑几天几夜,知道它一定能完成。

断点续传:C 写在 1996 年的设计

wget 的 -c 选项代表“continue”,开启断点续传。它的实现方式非常优雅:HTTP 协议本身就支持 Range 头,请求“从某个字节开始到结尾”的数据。wget 在下载中断时记录已经收到的字节数,下次启动时自动发 Range 请求,让服务器从断点处继续发送。

这套逻辑 28 年没变过。它不依赖任何外部状态,只在用户本地保存一个隐藏文件记录进度,因此即使 wget 进程被 kill -9 强制结束,下次启动也能恢复。这种“抗中断”特性,是 wget 在弱网环境、长时间任务里无可替代的根本原因。

与 curl 的本质区别

很多人搞不清 wget 和 curl 的区别。一句话总结:wget 是“用户视角”的下载器,curl 是“程序员视角”的数据传输工具。

wget 假设用户想做的事情就是“把文件存下来”,所以它默认保存、自动重试、智能处理重定向、安静地完成工作。curl 假设用户想做的事情是“和各种协议的服务器交换数据”,所以它默认把数据打印到 stdout、需要显式 -o 才保存、需要显式 -L 才跟随重定向、提供了 200 多个精细参数。

这两套哲学的差别,决定了 wget 在“批量下载文件”场景里更省心,curl 在“调试 HTTP 请求”场景里更灵活。一个运维写脚本会首选 wget,一个程序员写 API 测试会首选 curl。

wget 不擅长的领域

wget 也有一些明确的短板。它不支持 BT、磁力链接、ed2k 等 P2P 协议——这一点被 aria2 全面补齐。它不支持多线程分片——单文件下载速度上限取决于 TCP 单连接带宽。它没有内置的视频嗅探、站点抓取等高级功能——这些被 IDM 占据。它没有图形界面——桌面用户会觉得它“老派”。

但所有这些“短板”都是 wget 设计哲学的副产品。它的目标从来不是“成为最强的下载器”,而是“成为最可靠的下载器”。在 Linux 服务器、容器镜像、CI 流水线、嵌入式设备这些场景里,wget 仍然是默认选择。

wget 在云原生时代的传承

2020 年代以后,wget 出现了一个有趣的“继承者”:各种 Alpine Linux、BusyBox 镜像里都内置了 wget 的精简版。Docker 镜像构建时拉取依赖、CI 脚本下载二进制文件、运维调试时拉取日志——所有这些场景里,wget 的身影仍然无处不在。

一个 1996 年的工具仍然在 2026 年的云原生栈里发挥基础作用,这件事本身就是对 wget 设计哲学最好的背书。下一篇我们要讲的工具——curl 和 wget 几乎同时代诞生,但它走了一条完全不同的路。

参考资料