文件打包与压缩

LinuxBeginner
立即练习

简介

打包和压缩解决的是相关但不同的问题。归档会将目录树合并为一个数据流,同时保留文件名和目录结构。压缩则会以更紧凑的形式表示数据。.tar 文件是归档文件;.gz 文件是经过 gzip 压缩的数据;.tar.gz 文件是使用 gzip 压缩的 tar 归档文件。

你将创建一个小型项目,生成每种格式的归档,在提取前检查归档内容,将文件恢复到单独的目录中,然后把恢复后的数据与源数据进行比较。这种「检查—提取—验证」工作流可以避免盲目覆盖原始文件。

创建要保留的目录树

在本步骤中,你将创建一个小型源目录树,并记录打包和提取过程中必须保留的内容。

创建配置、笔记和数据目录:

cd /home/labex/project/archive-lab
mkdir -p source/{config,notes,data}

写入三个内容不同的文件:

printf 'mode=training\nport=8080\n' > source/config/app.conf
printf 'Archive the complete project tree.\n' > source/notes/README.txt
printf 'alpha,beta,gamma\n1,2,3\n' > source/data/sample.csv

使用 find 检查相对于源目录的普通文件路径:

find source -type f -printf '%P\n' | sort

创建并检查 Tar 归档

在本步骤中,你将创建一个未压缩的归档,并检查其中的成员名称。

tar 的主要操作字母包括:c 表示创建,t 表示列出内容,x 表示提取,f 表示指定归档文件名。使用 -C 在添加 source 之前切换 tar 的工作目录,这样可以避免在归档中保存很长的绝对路径:

cd /home/labex/project/archive-lab
tar -cf project.tar -C /home/labex/project/archive-lab source

源目录树仍然存在,因为创建归档时只会读取源文件,不会移动源文件。检查归档文件和其中一个原始文件:

ls -lh project.tar
ls -l source/config/app.conf

提取前先列出归档成员:

tar -tf project.tar > tar-members.txt
cat tar-members.txt

每个成员名称都应以 source/ 开头,并且不应以 / 开头。使用相对成员名称可以让恢复过程更安全,也更便于移植。

安全提取并比较结果

在本步骤中,你将把归档提取到一个空的目标目录,而不是提取到源目录,然后比较这两个目录树。

创建恢复目录,并使用 -C 指定提取目标:

cd /home/labex/project/archive-lab
mkdir tar-restore
tar -xf project.tar -C tar-restore

检查恢复后的路径:

find tar-restore -type f -printf '%P\n' | sort

递归比较两个目录树。当两棵目录树匹配时,diff -r 不会输出任何内容,并且会成功退出:

diff -r source tar-restore/source
echo "tar restore matches source" > tar-restore-ok.txt
cat tar-restore-ok.txt

使用 Gzip 压缩和解压缩单个文件

在本步骤中,你将看到 gzip 如何区别于归档:gzip 操作的是单个普通文件。

先复制一个文件以保持源目录树不变,然后压缩副本:

cd /home/labex/project/archive-lab
cp source/data/sample.csv sample-copy.csv
gzip sample-copy.csv

默认情况下,gzip 会用 sample-copy.csv.gz 替换输入文件:

ls -lh sample-copy.csv.gz
file sample-copy.csv.gz

解压缩该文件,并将其内容与原始文件进行比较:

gunzip sample-copy.csv.gz
cmp source/data/sample.csv sample-copy.csv
echo "gzip round trip matches" > gzip-round-trip-ok.txt
cat gzip-round-trip-ok.txt

Gzip 本身不会打包目录树;tar 负责提供目录结构。

创建并恢复压缩的 Tar 归档

在本步骤中,你将把 tar 打包与 gzip 压缩结合起来。z 选项会让 tar 将归档数据传递给 gzip 处理。

创建 project.tar.gz,并使用匹配的 -tzf 选项检查其内容:

cd /home/labex/project/archive-lab
tar -czf project.tar.gz -C /home/labex/project/archive-lab source
tar -tzf project.tar.gz > targz-members.txt
cat targz-members.txt

将归档提取到单独的目标目录,并验证目录树:

mkdir targz-restore
tar -xzf project.tar.gz -C targz-restore
diff -r source targz-restore/source
echo "tar.gz restore matches source" > targz-restore-ok.txt
cat targz-restore-ok.txt

扩展名可以向用户和工具说明文件格式:.tar.gz 明确表示这是一个经过 gzip 压缩的 tar 归档文件。

将项目作为 Zip 归档进行交换

在本步骤中,你将创建并检查 Zip 归档。Zip 是 Linux、macOS 和 Windows 上常见的格式。

zip -r 会递归添加目录树。先从实验根目录运行该命令,这样归档中保存的路径会以 source/ 开头:

cd /home/labex/project/archive-lab
zip -r project.zip source

不提取归档,直接列出其中的成员:

unzip -l project.zip

使用 -d 选择单独的目标目录,然后比较提取结果:

unzip -q project.zip -d zip-restore
diff -r source zip-restore/source
echo "zip restore matches source" > zip-restore-ok.txt
cat zip-restore-ok.txt

总结

你已经区分了打包与压缩,创建并列出了 tar 归档,完成了一次 gzip 压缩与解压缩往返操作,在 .tar.gz 中结合了这两种操作,并通过 Zip 交换了同一个目录树。更重要的是,你将内容恢复到单独的目录中,并通过比较文件内容进行验证,而不是仅仅假设归档创建成功就足够了。