Shell脚本如何批量下载URL列表文件
📖 目录导读
- 为什么需要批量下载URL列表?
- Shell脚本批量下载的核心工具:wget与curl
- 实战:用Shell脚本下载URL列表文件(含代码)
- 进阶技巧:断点续传、限速与并行下载
- 常见问题与错误处理
- Q&A:关于批量下载的典型疑问
- 总结与建议
为什么需要批量下载URL列表?
在日常运维、数据采集、文件同步或资源备份中,我们经常需要从大量URL中批量下载文件。

- 网站资源迁移(如JS、CSS、图片)
- 软件包列表(如Linux ISO镜像)
- 日志文件归档
- 学术数据集下载
手工逐个处理不仅低效,而且容易出错,Shell脚本凭借其轻量、跨平台、可自动化等优势,成为解决这类问题的首选方法。
Shell脚本批量下载的核心工具:wget与curl
在Linux/Unix/macOS环境中,wget 和 curl 是最常用的命令行下载工具。
| 工具 | 特点 | 适用场景 |
|---|---|---|
wget |
原生支持递归、断点续传、限速、镜像网站 | 稳定下载、批量处理、简易脚本 |
curl |
更灵活、支持更多协议(FTP、SFTP等) | 需自定义HTTP头、API调用 |
核心区别:wget 是“傻瓜式”批量下载利器,而 curl 更适合精细控制。
实战:用Shell脚本下载URL列表文件(含代码)
假设你有一个 urls.txt 文件,每行一个URL:
https://example.com/file1.zip https://example.com/file2.png https://example.com/file3.tar.gz
✅ 方案1:基于wget的简单脚本
#!/bin/bash
# download_list_wget.sh - 使用wget批量下载URL列表
URL_LIST="urls.txt"
DOWNLOAD_DIR="./downloads"
# 创建下载目录
mkdir -p "$DOWNLOAD_DIR"
# 读取URL列表并下载
while IFS= read -r url
do
if [ ! -z "$url" ]; then
echo "[INFO] 正在下载: $url"
wget -P "$DOWNLOAD_DIR" "$url" 2>> download_errors.log
fi
done < "$URL_LIST"
echo "[DONE] 所有下载任务完成,错误日志已保存至 download_errors.log"
✅ 方案2:基于curl的行级控制脚本
#!/bin/bash
# download_list_curl.sh - 使用curl批量下载并保留原文件名
URL_LIST="urls.txt"
DOWNLOAD_DIR="./downloads"
mkdir -p "$DOWNLOAD_DIR"
while IFS= read -r url; do
if [[ -n "$url" ]]; then
filename=$(basename "$url")
echo "[INFO] 正在获取: $filename"
curl -o "$DOWNLOAD_DIR/$filename" -sSL "$url" 2>> curl_errors.log
fi
done < "$URL_LIST"
echo "[完成] 所有文件已下载至 $DOWNLOAD_DIR"
提示:
-sSL参数分别表示静默模式、跟随重定向、安全连接。
进阶技巧:断点续传、限速与并行下载
🔄 断点续传
网络中断时,使用 -c 参数:
wget -c -P "$DOWNLOAD_DIR" "$url"
⏱ 限速(避免占满带宽)
wget --limit-rate=500k -P "$DOWNLOAD_DIR" "$url"
⚡ 并行下载(利用GNU Parallel)
# 安装parallel(Debian/Ubuntu)
sudo apt install parallel
# 并行下载(同时最多5个任务)
cat urls.txt | parallel -j 5 "wget -c -P ./downloads {}"
注意:并行数不宜过高(建议2~8),否则可能导致服务器封IP或本地资源耗尽。
常见问题与错误处理
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 下载失败,返回403/404 | URL过期或被屏蔽 | 检查URL有效性,使用 -U 设置User-Agent |
| 文件名重复或乱码 | URL不同但文件名相同 | 使用 -O 自定义输出路径(如 序号_文件名) |
| 脚本只下载了第一行 | 权限或读取方式错误 | 使用 while IFS= read -r 避免空格/换行问题 |
| 大量文件导致磁盘满 | 未做空间检测 | 下载前用 df -h 检查剩余空间 |
🛠 增强版脚本示例(包含错误处理)
#!/bin/bash
# robust_download.sh - 强化版批量下载
URL_FILE="urls.txt"
OUTPUT_DIR="./downloads"
LOG_FILE="download.log"
ERROR_LOG="error.log"
MAX_RETRIES=3
mkdir -p "$OUTPUT_DIR"
touch "$LOG_FILE"
counter=1
while IFS= read -r url; do
if [[ -z "$url" || "$url" == \#* ]]; then
continue
fi
filename=$(printf "%03d_%s" "$counter" "$(basename "$url")")
echo "[$(date +%H:%M:%S)] 开始下载: $filename" | tee -a "$LOG_FILE"
retries=0
while [[ $retries -lt $MAX_RETRIES ]]; do
if wget -c -q --timeout=30 --tries=1 -O "$OUTPUT_DIR/$filename" "$url" 2>> "$ERROR_LOG"; then
echo " ✓ 成功" >> "$LOG_FILE"
break
else
retries=$((retries + 1))
echo " ✗ 失败 (尝试 $retries/$MAX_RETRIES)" >> "$LOG_FILE"
sleep 5
fi
done
((counter++))
done < "$URL_FILE"
echo "[完成] 详情请查看 $LOG_FILE 和 $ERROR_LOG"
Q&A:关于批量下载的典型疑问
❓ Q1:如果URL中包含中文或特殊字符怎么办?
A:wget 和 curl 会自动进行URL编码,但如果字符未被正确转码,可以先用 urlencode 工具预处理(如 echo "URL" | python3 -c "import sys; from urllib.parse import quote; print(quote(sys.stdin.read().strip()))")。
❓ Q2:如何从下载的URL中提取文件名?
A:使用 basename 命令:
echo "https://example.com/path/file.zip" | xargs basename
输出:file.zip
❓ Q3:可以下载需要登录认证的文件吗?
A:可以,但需传递Cookie,使用 wget --load-cookies cookies.txt -P ./downloads URL 或 curl -b cookies.txt -O URL。
❓ Q4:如果URL列表非常大(10万+),脚本会卡死吗?
A:会,建议分批处理或使用 xargs -P 并行,但需注意系统句柄限制,更好的方案是使用 aria2c(支持并发、断点续传、Json-RPC控制)。
❓ Q5:如何验证下载文件的完整性?
A:生成MD5/SHA256校验文件,在下载后使用 md5sum 或 sha256sum 计算哈希值并对比。
总结与建议
通过Shell脚本批量下载URL列表文件,可以极大提升数据处理效率,核心要点:
- 优先使用
wget,因为它对批量下载、重试、断点续传有原生支持。 - 检查URL有效性:先随机测试几个URL,确认格式和权限。
- 做好日志与备份:记录每次下载的状态,方便排查。
- 控制资源消耗:合理使用
--limit-rate和-j并行参数,避免影响其他业务。 - 跨平台注意:macOS内置
curl,但wget需通过brew install wget安装;Windows可借助WSL或Git Bash。
延伸阅读:如果需要管理超大文件或海量URL,可考虑 aria2c(轻量多协议下载器)或 youtube-dl(针对视频站),但日常90%的批量下载场景,一个20行的Shell脚本就足够了。
这篇文章由AI根据搜索引擎收录的高质量技术博客综合生成,旨在提供可直接落地的Shell脚本批量下载方案,如果你在实际操作中遇到问题,欢迎在评论区留言。