tar 打包下载命令手册:逐段拆解与套用模板
适用场景:在 AutoDL / Linux 服务器上把文件夹打包成单文件,以便下载到本地
为什么要打包:JupyterLab 等网页文件管理器不支持下载文件夹,只能下载单个文件
建立时间:2026-10-15
来源实例:autodl-container-38ef40b880-8646dcf9
一句话用途:记住一条命令模板,换文件夹名就能反复套用
目录
- 0. 一键套用模板
- 1. 原命令逐段拆解
- 1.1 七个片段的含义
- 1.2 cf 两个字母的含义
- 1.3 为什么执行完没有任何输出
- 2. 为什么要排除 git 目录
- 2.1 同一份数据在硬盘上存了两遍
- 2.2 体积对照
- 2.3 怎么验证自己有没有误打包
- 2.4 什么情况下才该保留
- 3. 为什么一律不加 z 或 J
- 4. 关于 cd 的两点澄清
- 4.1 波浪号和斜杠的区别
- 4.2 结论:不能直接换
- 4.3 确实想用绝对路径怎么办
- 5. 通用套用模板
- 5.1 模板 A:先切换目录再打包
- 5.2 模板 B:用 C 参数不改当前目录
- 5.3 只打包某个子目录
- 6. 常见报错排查表
- 7. 打包后的验收清单
- 8. 下载中断时的分卷方案
- 9. tar 常用参数速查
- 10. 速记卡
0. 一键套用模板
最常用形式,只需改动三处:
cd<文件夹所在的目录>&&tar--exclude='.git'-cf<输出名>.tar<要打包的文件夹名>实例演进:
| 想打包什么 | 命令 |
|---|---|
| NTURain 训练集仓库(本次案例) | cd ~ && tar --exclude='.git' -cf SPAC-SupplementaryMaterials.tar SPAC-SupplementaryMaterials |
| RainMamba 代码目录 | cd ~ && tar --exclude='.git' -cf RainMamba.tar RainMamba |
| autodl-tmp 下的数据集 | cd /root/autodl-tmp && tar -cf mydata.tar mydata |
| 纯数据目录(无 git) | cd ~/data && tar -cf dataset_v2.tar dataset_v2 |
记忆口诀:
cd 到父目录 → tar -cf 输出名.tar 文件夹名 → 有 git 就加 --exclude='.git'通用写法(连 cd 都省掉):
tar--exclude-vcs-cf<输出名>.tar-C<父目录><文件夹名>--exclude-vcs会自动排除.git/.svn/.hg等所有版本控制目录,比手写--exclude='.git'更省心。
1. 原命令逐段拆解
完整命令:
cd~&&tar--exclude='.git'-cfSPAC-SupplementaryMaterials.tar SPAC-SupplementaryMaterials1.1 七个片段的含义
| # | 片段 | 含义 |
|---|---|---|
| 1 | cd ~ | 切换到当前用户家目录。root 用户 →/root。这一句必需,因为后面两个路径都写成了相对形式 |
| 2 | && | 逻辑与:前一条命令成功(退出码 0)才执行后一条。若cd失败,tar 不会在错误目录里乱跑 |
| 3 | tar | 归档工具(tape archive),把多个文件/目录合并成单个文件 |
| 4 | --exclude='.git' | 排除名为.git的目录。这是glob 模式,不含/时会匹配任意层级中叫.git的条目。单引号是 shell 强引用,防止特殊字符被提前展开(此处无特殊字符,加引号属规范习惯) |
| 5 | -cf | 两个选项合并写:-c= create(创建归档)+-f= file(用文件而非标准输出,必须紧跟归档名) |
| 6 | SPAC-SupplementaryMaterials.tar | 输出归档文件名(-f的实参) |
| 7 | SPAC-SupplementaryMaterials | 要打包的源目录(相对当前目录~) |
执行后的结果位置:
/root/SPAC-SupplementaryMaterials.tar ← 归档文件本体(604 MB) └── SPAC-SupplementaryMaterials/ ← 归档内的路径前缀 └── Dataset_Training_Synthetic/ ← 33 个 rar ├── t1_Rain_01.rar └── ... ×33包内保留了目录前缀(因为源参数写的是相对目录名)。本地解开后得到完整目录结构,不会散落一地文件。
1.2 cf 两个字母的含义
tar-c-fSPAC-SupplementaryMaterials.tar SPAC-SupplementaryMaterials# ↑ ↑ ↑# │ │ └── 归档文件名(-f 的实参,必须紧贴其后,中间不能插别的选项)# │ └───── 写入文件而非标准输出# └──────── 创建新归档(create)常见误写:
| 错误写法 | 问题 |
|---|---|
tar -c SPAC-SupplementaryMaterials.tar dir/ | 缺-f,tar 会把归档内容喷到终端屏幕上(二进制乱码刷屏) |
tar -cf dir/ SPAC-SupplementaryMaterials.tar | 参数顺序颠倒:-f后面跟的必须是输出名,不是源目录 |
tar cf ... | 老式写法(不带-),能跑但可读性差,建议统一用-cf |
1.3 为什么执行完没有任何输出
因为没有加-v(verbose)。tar 在静默模式下成功时不打印任何内容——这符合 Unix 哲学:“无消息即成功”(No news is good news)。
# 想看到打包了哪些文件,加 -v:tar-cvfSPAC-SupplementaryMaterials.tar SPAC-SupplementaryMaterials判断成功的正确方式是看退出码,而不是看有没有输出:
cd~&&tar--exclude='.git'-cfSPAC-SupplementaryMaterials.tar SPAC-SupplementaryMaterials&&echo"打包成功"2. 为什么要排除 git 目录
2.1 同一份数据在硬盘上存了两遍
Git 的工作方式和普通文件夹不一样。以本次的稀疏检出目录为例:
/root/SPAC-SupplementaryMaterials/ ├── Dataset_Training_Synthetic/ ← 工作区:604 MB(checkout 出来的 33 个 rar) │ ├── t1_Rain_01.rar │ └── ... ×33 └── .git/ └── objects/pack/*.pack ← 对象库:~603 MB(同样这 33 个 rar 的另一种存放形式)关键在于--filter=blob:none这个参数的作用是"延迟下载",不是"不下载":
- clone 时:只拉 8 个对象(目录树信息),文件内容一律不拿
- 执行
git checkout时:git 才把那 603.15 MiB 的内容拉下来 - 拉下来的内容先存进
.git/objects/pack/(就是传输日志里那个 603.15 MiB) - 然后从对象库再写出一份到工作区的
Dataset_Training_Synthetic/
→ 同一批 rar,在磁盘上占了两份。
打比方:
.git是书店的仓库,工作区是书架。你要寄给朋友的是书架上的书,但不排除.git就等于把仓库连同书架一起装箱——同一批书装两遍。
2.2 体积对照
| 写法 | tar 体积 | 下载风险 |
|---|---|---|
tar --exclude='.git' -cf ...✅ | 604 MB | 低 |
tar -cf ...(不排除) ❌ | ~1.2 GB | 高——下载量翻倍,中途断线概率也翻倍 |
单个 1.2 GB 文件走网页下载,基本必然要重来一两次。
2.3 怎么验证自己有没有误打包
先看源目录的体积构成:
du-h--max-depth=1~/SPAC-SupplementaryMaterials|sort-h输出示例:
604M /root/SPAC-SupplementaryMaterials/Dataset_Training_Synthetic 605M /root/SPAC-SupplementaryMaterials/.git 1.2G /root/SPAC-SupplementaryMaterials最后一行是总数,前两行各占一半。⚠️du的父目录会包含子目录,所以单看总数会误以为"数据有 1.2 GB",其实真正需要的只有 604 MB。
再看归档本身:
ls-l~/SPAC-SupplementaryMaterials.tartar-tf~/SPAC-SupplementaryMaterials.tar|wc-l| 观察项 | 干净(已排除 .git) | 误含 .git |
|---|---|---|
ls -l字节数 | ≈ 604 MB | ≈ 1.2 GB |
tar -tf | wc -l | 约 36 行 | 上百行(多出大量 git 内部文件) |
⚠️ 一个反直觉的坑
tar -tf xxx.tar | grep -c '\.rar$'这个计数无法用来判断是否误含.git。
原因:.git里的文件叫xxxx.pack、xxxx.idx,压根不含.rar字样——两种情况数出来都是 33。要判断必须看ls -l的字节数或tar -tf | wc -l的行数。
2.4 什么情况下才该保留
只有一种:你要在这台机器上继续做 git 操作——比如再 checkout 仓库里的其他目录(测试集、代码),或者git pull更新。
如果目标只是把数据带回本地,本地不需要这些 git 元数据(本地有 WinRAR 就够了)。排除还有两个附带好处:
- 包里不会夹带服务器路径、git 历史、远端地址等与研究无关的信息,交付他人时更干净
- 下载量减半
3. 为什么一律不加 z 或 J
| 写法 | 作用 | 本场景结果 |
|---|---|---|
tar -cf | 把文件夹变成单个文件 | 体积不变(604 MB → 604 MB) |
tar -czf | 打包 + gzip 压缩 | 收益 ≈ 0,白烧 CPU |
tar -cJf | 打包 + xz 压缩 | 更慢,收益依旧极小 |
原因:包内是已经压过的 rar(内含 jpg 图片),这些格式的熵值已接近极限,二次压缩只能再压掉约 0.5%,却要付出几十分钟 CPU 时间。
必须区分两件事:
| 解决的问题 | |
|---|---|
tar(不加 z) | 文件夹 → 单文件(这才是 AutoDL 下载限制的根源) |
-z/-J | 体积太大 → 体积变小(本场景不需要) |
JupyterLab 限制的是不能下载文件夹,不是"只能下载压缩包"。所以tar -cf完全够用。看到有人写tar -czf打 rar 包,那是无意义的。
特例:如果打包的是大量小文本文件(如几千个 .py / .txt / .json),那
-z是真有用的,能压到 1/5 甚至更低。判断标准是内容是否已被压缩。
4. 关于 cd 的两点澄清
4.1 波浪号和斜杠的区别
| 写法 | 展开为 | 含义 |
|---|---|---|
~ | /root(root 用户) | 家目录(home directory) |
$HOME | /root | 与~完全等价 |
/ | / | 文件系统根目录(最顶层) |
. | 当前所在目录 | — |
.. | 上一级目录 | — |
术语澄清:中文日常口语常把"根目录"用来指家目录(~),但在 Linux 语境里/才是根目录,~叫家目录。两者是不同层级:
/ ← 根目录(cd / 到这里) ├── bin/ etc/ home/ tmp/ usr/ var/ ... └── root/ ← root 用户的家目录(cd ~ 到这里) ├── SPAC-SupplementaryMaterials/ ← 本次打包的目录在这里 └── autodl-tmp/4.2 结论:不能直接换
cd ~换成cd /会失败:
cd/&&tar--exclude='.git'-cfSPAC-SupplementaryMaterials.tar SPAC-SupplementaryMaterials# tar: SPAC-SupplementaryMaterials: Cannot stat: No such file or directory原因:SPAC-SupplementaryMaterials在/root/下,不在/下。cd /之后 tar 在当前目录(/)里找不到这个相对路径。
反证:本次命令是从/提示符出发的——
root@...:/# cd ~ && tar --exclude='.git' -cf ... root@...:~# ← 提示符变成 ~,说明 cd 确实切到了 /root 并成功找到目录如果目录真在/下,cd ~反而会失败。
验证方法:
ls-d/root/SPAC-SupplementaryMaterials# 存在 ✅ls-d/SPAC-SupplementaryMaterials# 不存在 ❌4.3 确实想用绝对路径怎么办
有两种写法,效果不同:
写法一:源也用绝对路径
cd/&&tar--exclude='.git'-cf/root/SPAC-SupplementaryMaterials.tar /root/SPAC-SupplementaryMaterials能跑,但 GNU tar 会打印警告:
tar: Removing leading `/' from member names因为 Tar 格式不存储绝对路径(避免解压时覆盖系统文件)。结果是包内路径变成root/SPAC-SupplementaryMaterials/...,本地解开后多出一层root/目录,不够干净。
写法二:用-C参数(推荐)
tar--exclude='.git'-cf~/SPAC-SupplementaryMaterials.tar-C~ SPAC-SupplementaryMaterials-C ~让 tar 在读取文件之前切换到~,效果等同于cd ~,但归档内的路径仍然是干净的相对路径。这是脚本里最推荐的写法——不改变当前所在目录。
5. 通用套用模板
5.1 模板 A:先切换目录再打包
适合交互式终端使用(最直观):
cd<文件夹所在目录>&&tar--exclude='.git'-cf<输出名>.tar<文件夹名>要点:
cd的目标是父目录,不是文件夹本身- 最后两个参数都是相对于 cd 之后目录的路径
- 输出名建议写简单点,不要带
/,否则会跑到别处
# 正例cd~&&tar--exclude='.git'-cfRainMamba.tar RainMamba# 反例:cd 进了文件夹本身,然后又找同名子目录 → 必然失败cd~/RainMamba&&tar-cfRainMamba.tar RainMamba5.2 模板 B:用 C 参数不改当前目录
适合写进脚本 / 连续打包多个目录:
tar--exclude-vcs-cf<输出名>.tar-C<父目录><文件夹名>实例——一次打包三个目录:
tar--exclude-vcs-cf/root/backup_1.tar-C/root RainMambatar--exclude-vcs-cf/root/backup_2.tar-C/root DRSformertar--exclude-vcs-cf/root/backup_3.tar-C/root/autodl-tmp mydata注意-C的相对路径陷阱:多个-C会累积(第二次-C是相对第一次的结果)。安全做法是每个-C都用绝对路径。
5.3 只打包某个子目录
场景:只想把Dataset_Training_Synthetic带走,不要外层仓库结构。
tar-cf~/NTURain_train.tar-C~/SPAC-SupplementaryMaterials Dataset_Training_Synthetic解读:-C ~/SPAC-SupplementaryMaterials先切进仓库目录,然后打包其下的Dataset_Training_Synthetic。得到 604 MB 的包,解开后直接就是Dataset_Training_Synthetic/,少一层嵌套。
6. 常见报错排查表
| 报错 / 现象 | 原因 | 解决 |
|---|---|---|
Cannot stat: No such file or directory | 源目录路径不对(相对路径基于错误的当前目录) | pwd+ls确认位置;或用绝对路径 +-C |
Removing leading '/' from member names | 用绝对路径作源参数 | 无害,但包内会多出root/层级;改用-C更干净 |
Cowardly refusing to create an empty archive | 源写成了不存在或空的路径 | 检查拼写;确认目录非空 |
| 终端刷出大量二进制乱码 | 忘了-f,归档内容输出到了屏幕 | 加-f 输出名 |
| 打完包提示符没变、命令像没反应 | tar 静默模式正常行为 | 加&& echo OK确认,或查退出码echo $? |
| 归档体积是预期的两倍 | 没排除.git | 加--exclude='.git'或--exclude-vcs |
| 打包耗时极长、CPU 飙高 | 误加了z/J | 去掉压缩选项 |
| 解开后多一层同名目录 | 源参数写的是目录名本身(正常) | 若想少一层,用-C <父目录> <子目录> |
归档里出现了./开头的路径 | 用了tar -cf x.tar . | 改用明确的目录名 |
7. 打包后的验收清单
打包完成后(服务器端):
ls-lh~/SPAC-SupplementaryMaterials.tartar-tf~/SPAC-SupplementaryMaterials.tar|head-5tar-tf~/SPAC-SupplementaryMaterials.tar|grep-c'\.rar$'| 检查项 | 期望值 |
|---|---|
ls -lh体积 | ≈ 604 MB(若 1.2 GB 说明含了.git) |
tar -tf | head -5 | 正常显示SPAC-SupplementaryMaterials/...路径 |
grep -c '\.rar$' | 33(本次数据集的 rar 总数) |
记录字节数,供下载后比对:
ls-l~/SPAC-SupplementaryMaterials.tar|awk'{print $5}'→ 把这个数字抄下来。
下载完成后(本地端):
ls-lSPAC-SupplementaryMaterials.tar→字节数与服务器端完全一致才算下载成功。
⚠️这是本手册最重要的一条:不要靠"能打开"判断完整性。历史教训是一次下载的文件恰好截断在整数 MiB 边界上(340,787,200 字节 = 恰好 325 MiB),看起来大小"正常",实际已损坏,WinRAR 报"不可预料的压缩文件末端"。必须对数字。
可选:用 MD5 做终极校验
# 服务器端md5sum ~/SPAC-SupplementaryMaterials.tar# 本地端(Git Bash)md5sum SPAC-SupplementaryMaterials.tar# 本地端(PowerShell,输出大写,内容相同)Get-FileHash-AlgorithmMD5".\SPAC-SupplementaryMaterials.tar"8. 下载中断时的分卷方案
症状:单文件走网页下载反复中断,或下完发现大小对不上。
对策:切分成多个小卷,只重下失败的那一卷。
第一步:算清楚要切几卷
604 MB = 575.5 MiB 200 MiB × 3 = 600 MiB > 575.5 MiB → 分 3 卷:part00(200M) + part01(200M) + part02(175.5M)第二步:切分
cd~&&split-b200M-d-a2SPAC-SupplementaryMaterials.tar SPAC-SupplementaryMaterials.tar.partls-lh~/SPAC-SupplementaryMaterials.tar.part*-b 200M每卷 200 MiB |-d用数字后缀 |-a 2后缀两位数(00/01/02)
第三步:逐卷下载(网页下载 3 个文件,比下 1 个大文件稳)
第四步:本地合并
# Git Bashcd"本地下载目录"catSPAC-SupplementaryMaterials.tar.part00 SPAC-SupplementaryMaterials.tar.part01 SPAC-SupplementaryMaterials.tar.part02>SPAC-SupplementaryMaterials.tar⚠️必须按 part00 → part01 → part02 顺序写,不要图省事写cat *.part*(某些排序下会错乱)。
# 或 Windows CMDcopy /b part00+part01+part02 SPAC-SupplementaryMaterials.tar第五步:校验
md5sum SPAC-SupplementaryMaterials.tar# 与服务器端 md5sum 对拍tar-tfSPAC-SupplementaryMaterials.tar|grep-c'\.rar$'# 应为 33分卷方案的核心价值:某一卷下载失败时只需重下该卷(200 MB),不必整体重来(604 MB)。
9. tar 常用参数速查
| 参数 | 全称 | 含义 |
|---|---|---|
-c | create | 创建新归档 |
-f | file | 指定归档文件名(必须紧跟文件名) |
-v | verbose | 打印处理的文件列表 |
-t | list | 列出归档内容(不解开) |
-x | extract | 展开归档 |
-C | directory | 切换目录(读取前 / 写出前) |
--exclude= | — | 排除匹配的条目(glob 模式) |
--exclude-vcs | — | 自动排除.git/.svn/.hg/.bzr等版本控制目录 ✅ 推荐 |
-p | preserve | 保留权限信息 |
-z | gzip | gzip 压缩 ⚠️ 本场景不用 |
-J | xz | xz 压缩 ⚠️ 本场景不用 |
-r | append | 向已有归档追加文件 |
-u | update | 只追加比归档中更新的文件 |
必记的三组:
tar-cfout.tar dir/# 打包(最常用)tar-tfout.tar# 查看内容(不展开)tar-xfout.tar# 展开10. 速记卡
日常场景 → 直接抄
# ① 打包某个文件夹(排除 git,最常用)cd~&&tar--exclude='.git'-cf输出名.tar 文件夹名# ② 打包但不改变当前目录(脚本友好)tar--exclude-vcs-cf~/输出名.tar-C~ 文件夹名# ③ 只打包仓库里的某个子目录tar-cf~/输出名.tar-C~/仓库名 子目录名# ④ 查看包内容 / 体积 / 文件数tar-tf~/输出名.tar|head-5ls-lh~/输出名.tartar-tf~/输出名.tar|wc-l# ⑤ 下载前先记字节数(供本地比对)ls-l~/输出名.tar|awk'{print $5}'# ⑥ 下载中断就分卷split-b200M-d-a2~/输出名.tar ~/输出名.tar.part四条铁律
cd到父目录,不是文件夹本身- 有
.git就加--exclude='.git'(否则体积翻倍) - 永远不加
z(rar/jpg 已压缩,白烧 CPU) - 下载后对字节数,不要靠"能打开"
three 个最容易混淆的路径
| 写法 | 实际位置 |
|---|---|
~ | /root(家目录) |
/ | 文件系统最顶层(不是你的文件所在处) |
. | 当前目录 |
文档结束 · 2026-10-15