主题
大文件分卷与光盘交付
把 10 GB 以上的离线包切成若干卷、刻盘带到现场、在目标机上合并校验解包。本文记录实测验证过的完整链路。
与 Linux 常用命令 中"对 tar.gz 文件进行切割和合并及 md5 校验"一节的关系:那节是纯 Linux 侧的切割思路,本文补上 Windows 侧分卷、光盘刻录约束、以及 PowerShell 编码坑。
结论
- 已经是
.tar.gz的成品包不要再打一次tar。split只做字节切片,tar只负责最后解包,两者不叠加。 - Windows 上
split/md5sum/bash来自 Git for Windows 的Git\usr\bin,该目录不在 PATH 里(安装程序只加了Git\cmd),需全路径调用或临时补 PATH。 - PowerShell 的
>重定向写 UTF-16LE,生成的 md5 校验表md5sum -c读不了,必须用cmd /c做重定向。 - 光盘必须用 UDF 格式。ISO9660-only 会截断长文件名,分卷顺序错乱,合并出来是坏包。
- 分卷校验要逐卷做,这样哪张盘划伤在合并前就能定位,不用重刻全部。
适用范围与环境
| 环节 | 运行环境 |
|---|---|
| 分卷 | Windows PowerShell 5.1(用 Git 提供的 coreutils)或 Linux |
| 生成校验表 | 同分卷侧 |
| 刻录 | Windows 刻录软件 |
| 读取 / 合并 / 校验 / 解包 | 现场 Linux 服务器 |
实测样例:Devops_Kubernetes_arm64_v8.20.0.tar.gz,18,690,897,878 字节(17.41 GB),按 7 GB/卷切分。
前置条件
- 原包完整,且已有一个权威的 md5/sha256 值(通常随包提供
.md5文件)。 - 输出盘剩余空间 ≥ 原包大小。分卷不压缩,所有分卷加起来等于原包体积。
- Windows 侧已装 Git for Windows(提供
split.exe/md5sum.exe)。
先确认 coreutils 的位置,Windows 上不要假设它在 PATH 里:
powershell
Get-Command split -ErrorAction SilentlyContinue
# 无输出 = 不在 PATH,用下面两种方式之一步骤
1. 分卷
Windows PowerShell(已验证):
powershell
# 方式 A:临时补 PATH,仅当前窗口有效
$env:Path += ";D:\software\Git\usr\bin"
cd <包所在目录>
split -b 7G -d -a 2 Devops_Kubernetes_arm64_v8.20.0.tar.gz devops_pkg.part-
# 方式 B:不动 PATH,直接写全路径(路径无空格时不需要 & 调用运算符)
D:\software\Git\usr\bin\split.exe -b 7G -d -a 2 Devops_Kubernetes_arm64_v8.20.0.tar.gz devops_pkg.part-Linux 侧等价命令:
bash
cd <包所在目录>
split -b 7G -d -a 2 Devops_Kubernetes_arm64_v8.20.0.tar.gz devops_pkg.part-参数含义:
| 参数 | 作用 |
|---|---|
-b 7G | 每卷 7 GiB(7 × 1024³ = 7,516,192,768 字节)。要十进制 7,000,000,000 用 -b 7GB |
-d | 后缀用数字(00、01…)而不是字母,保证 glob 排序正确 |
-a 2 | 后缀宽度 2 位。分卷数会超过 99 时改 -a 3 |
| 末位参数 | 输出前缀,实际文件名为 前缀00、前缀01… |
本样例产出 3 个文件:part-00 7 GiB、part-01 7 GiB、part-02 3.41 GiB。
输出文件名不要太长。 刻录到 ISO9660 时超过 8.3 的名字会被截断,短前缀(如 devops_pkg.part-)更稳。
2. 生成分卷校验表
Windows PowerShell(已验证):
powershell
cmd /c "D:\software\Git\usr\bin\md5sum.exe devops_pkg.part-* > devops_pkg.parts.md5"Linux 侧:
bash
md5sum devops_pkg.part-* > devops_pkg.parts.md5这里必须用
cmd /c包一层。 PowerShell 的>默认写 UTF-16LE(带 BOM),md5sum -c会报no properly formatted MD5 checksum lines found。 自检方法——读首字节:[System.IO.File]::ReadAllBytes($f)[0..3],55 54 46 2D是 UTF-16 BOM(错), 纯 ASCII 哈希表应以十六进制字符开头(如62 36 36 39=b669)。
3. 刻录
一张盘放一个分卷;把 devops_pkg.parts.md5 一起刻进第一张盘,现场才有校验依据。
格式必须选 UDF,不要 ISO9660-only。
容量要按介质算,7 GB/卷不是随便定的:
| 介质 | 容量 | 能否装 7 GB/卷 |
|---|---|---|
| CD-R | 700 MB | 否 |
| DVD-5 | 4.7 GB | 否 |
| DVD-9(双层) | 8.5 GB | 是,留余量 |
| BD-25 | 25 GB | 是 |
| BD-50 | 50 GB | 是 |
如果手上只有 DVD-5,把分卷大小改成 -b 4500M,本样例会切成 4 卷。
4. 现场读取(Linux)
逐张盘挂载并拷贝:
bash
mkdir -p /mnt/cdrom /root/devops
mount -t udf /dev/sr0 /mnt/cdrom
cp /mnt/cdrom/devops_pkg.part-* /root/devops/
umount /mnt/cdrom换盘后重复。所有分卷拷到同一目录即可。
5. 合并、校验、解包(Linux)
bash
cd /root/devops
# 5.1 先逐卷校验——坏盘在这一步就能定位,不必等合并完
md5sum -c devops_pkg.parts.md5
# 5.2 按序合并
cat devops_pkg.part-* > Devops_Kubernetes_arm64_v8.20.0.tar.gz
# 5.3 整包校验
md5sum Devops_Kubernetes_arm64_v8.20.0.tar.gz # 期望 9aa9afa93c273f86c6c8a40d5c24c3b9
# 5.4 解包
tar -xzf Devops_Kubernetes_arm64_v8.20.0.tar.gz如果随包提供的是裸哈希(.md5 文件里只有 32 个十六进制字符,没有文件名),md5sum -c 无法直接消费它,改用:
bash
[ "$(md5sum Devops_Kubernetes_arm64_v8.20.0.tar.gz | cut -d' ' -f1)" = 9aa9afa93c273f86c6c8a40d5c24c3b9 ] \
&& echo MD5-OK || echo MD5-FAIL机制说明
为什么成品包不要再 tar 一次。 常见的 tar czf - dir | split -b 7G - x.part- 写法适用于"从目录现场打包",因为 tar 的 stdout 直接流进 split,不落中间文件。但对已经是 .tar.gz 的成品,再走一遍只是把已压缩的数据重新 gzip 一次:耗掉大量 CPU 和时间,体积几乎不变。此时 split 单独作用即可。
-d 为什么重要。 split 的默认后缀是字母(aa、ab…)。数字后缀配合固定宽度,字典序与数值序一致,cat part-* 才能按正确顺序拼接。字母后缀在超过 26 卷时(za → zab)也会乱序。
分卷为什么不能单独解压。 split 是纯字节切片,切点与 gzip 的块边界无关。任何单卷都不构成合法的 gzip 流,必须先按序拼回完整文件。
风险与边界
- 分卷不压缩,只做切分:所有分卷体积之和 = 原包体积,不会变小。输出盘需预留同等空间。
cat part-*依赖文件名排序:前缀固定宽度 +-d才安全;手工改过卷名或刻录时名字被截断都会破坏顺序。逐卷md5sum -c是发现这类问题的必要手段。- 在线切割不是原子的:若原包正在被写入,切出来的分卷可能不一致。切割前确认原包写入已结束。
- 光盘比硬盘脆弱:UDF 格式 + 逐卷校验能把"读不出来"和"读出来是坏的"区分开;每卷单独校验值就是为这个场景准备的。
- md5 只用于校验传输完整性,不是防篡改手段。对外交付如需防篡改应改用 sha256。
验证与实际结果
以下为已验证结果(2026-09-11,本机实测)。
用 30 字节探针文件跑完整链路,确认切分—校验—合并三个环节字节无损:
text
全路径 split.exe 切分 -> 29 个分卷,正常
cmd /c 生成的校验表首字节 -> 62 36 36 39("b669",纯 ASCII)
md5sum -c 逐卷回读 -> 全部 OK
按序 copy /b 合并回原文件 -> md5 与源文件完全一致(8a250fcd46bdbb7ab60d0973c4051308)反例(同一实测中确认的失败现象):
text
PowerShell 的 > 重定向生成校验表 -> md5sum -c 报 no properly formatted MD5 checksum lines found
用户窗口直接执行 split -> CommandNotFoundException(因为 Git\usr\bin 不在 PATH)注意:在 Hermes terminal 里
Get-Command split可能解析成功,而用户自己的 PowerShell 窗口失败——两者 PATH 不同。给出依赖外部 exe 的命令前,应查持久 PATH:[Environment]::GetEnvironmentVariable('Path','Machine')。
参考来源
无外部资料,全部来自本机实测。