CLI AI

用 curl 断点续传下载文件而不损坏

2026-06-29

直接的判断方法是 curl -sI https://example.com/big.iso | grep -i 'accept-ranges':响应里没有 Accept-Ranges: bytes,说明服务器根本不支持续传,-C - 也救不了你。跳过这一步,你就可能撞上 curl 最难缠的失败模式:退出码是 0,屏幕上没有任何异常提示,文件却被悄悄截断了。下面讲怎么正确续传、怎么抓住这个坑、怎么重试,以及最后怎么确认文件真的是完整的。

1. 服务器到底支不支持续传

clai
$ clai 检查服务器是否支持断点续传→ curl -sI https://example.com/big.iso | grep -i 'accept-ranges'

响应里没有 Accept-Ranges: bytes 这个头,说明续传根本不可能,-C - 也改变不了这一点。花三十秒检查一下,能省下大文件快下完时中断带来的一小时痛苦。

2. 正常的续传

clai
$ clai 续传这个中断的下载→ curl -C - -O https://example.com/big.iso

-C - 告诉 curl 自己根据本地文件大小算出偏移量。-O 用 URL 里的文件名保存。如果文件已经下完了,curl 只会告诉你没有可续传的内容。

3. 陷阱:服务器不支持 Range

clai
$ clai 下载文件并检查它是否完整→ curl -C - -o part.bin http://example.com/big.bin && cmp -s part.bin original.bin && echo intact || echo TRUNCATED

整篇文章就是为了这一行。服务器忽略 Range 时,curl 照样以状态码 0 退出——没有错误,没有警告——文件就停在原来中断的地方。在真实服务器上测过:实际到手 51200 字节而不是 200000 字节,全程没有一条错误信息。续传下来的文件永远不要不检查就相信——用大小、cmp,或者校验和。

4. 重试直到下完为止

clai
$ clai 用重试的方式下载这个文件直到完全下完→ curl --retry 10 --retry-delay 5 --retry-all-errors -C - -O https://example.com/big.iso

--retry 处理网络故障,--retry-all-errors 把 5xx 响应也算进去。配合 -C -,每次重试都从上次中断的地方继续,而不是从头再来。

5. 限速,避免占满带宽

clai
$ clai 下载文件但限速到每秒一兆字节→ curl --limit-rate 1M -C - -O https://example.com/big.iso

在还有别的东西需要带宽的机器上很有用。支持 k、M、G 后缀。

6. 确认下载到的就是对的文件

clai
$ clai 校验刚下载文件的校验和→ curl -sO https://example.com/big.iso.sha256 && sha256sum -c big.iso.sha256

任何续传流程的最后一步。校验和吻合是唯一能证明这个拼接出来的文件是完整的证据——大小可能一样,内容却不一定。

常见坑

  • curl 从不会告诉你续传失败了。 退出码是 0,文件却是截断的。事后检查是唯一靠谱的防线。
  • 如果续传过程中服务器上的文件变了,你会得到一堆垃圾数据。 旧版本和新版本的字节会被拼在同一个文件里。拿不准就删掉部分文件重新下载。
  • -C - 配上指向旧文件的 -o 很危险。 curl 只看这个路径上已经有什么文件就续传什么,它只认文件名,不管这些字节是从哪来的。

相关问题

wget 还是 curl? wget -c 有同样的续传逻辑,下单个文件更简单。curl 在脚本里更灵活,也出现在没装 wget 的机器上。

怎么通过 ssh 续传? rsync --partial --progress --append-verify——既能续传,也能校验已经下载的部分。

"bad download resume" 是什么意思? curl 没能从正确的偏移量继续——服务器不支持 Range,或者文件被改动过。从头开始下载。

相关阅读

别再靠猜续传下载该用哪个 curl 参数了——描述需求,CliAI 帮你写命令。一行命令安装。