深入理解 tar:在 Linux 系统中的文件归档利器
在 Unix 和 Linux 系统中,tar
是一个非常流行的文件归档工具。它能将多个文件和目录组合成一个单一的归档文件,便于存储、传输和备份。
tar
的名字来源于 “Tape Archive”,最初是设计用来在磁带设备上顺序写入数据的,因此也被称为 “tarball”。它能够创建归档文件,但默认情况下不会进行压缩。为了减小文件大小,通常会结合其他压缩技术来使用。
tar
工具在大多数 Linux 发行版中都是预装的,并且这种文件格式在包括 Windows 和 macOS 在内的其他操作系统中也通过各种工具和应用程序得到了支持。
本文将深入探讨 tar
命令及其常用选项,通过实例演示其多种用途。
现在,让我们开始探索吧…
创建 tar 归档
创建一个基本的未压缩 tar
归档文件,其命令语法如下:
$ tar cvf <归档文件名> <要归档的文件列表>
其中 c
表示创建,v
表示显示详细输出,f
表示指定归档文件的名称。 按照惯例,我们通常将 tar
文件的扩展名命名为 .tar
。 要归档的文件可以使用通配符来表示,也可以指定一个或多个文件名/路径。
例如,假设当前目录下有三个文件:
$ ls -l total 12 -rw-r--r-- 1 abhisheknair abhisheknair 13 Sep 12 20:08 file1.txt -rw-r--r-- 1 abhisheknair abhisheknair 19 Sep 12 20:08 file2.txt -rw-r--r-- 1 abhisheknair abhisheknair 24 Sep 12 20:08 file3.txt $
如果想要创建一个包含这三个文件的 tar
归档,可以使用以下命令:
$ tar cvf archive.tar * file1.txt file2.txt file3.txt $ ls -l archive.tar -rw-r--r-- 1 abhisheknair abhisheknair 10240 Sep 12 20:15 archive.tar $
或者,也可以只指定要归档的特定文件,如下所示:
$ tar cvf archive1.tar file1.txt file2.txt file1.txt file2.txt $ ls -l archive1.tar -rw-r--r-- 1 abhisheknair abhisheknair 10240 Sep 12 20:15 archive1.tar $
创建压缩归档(GZ 格式)
tar
不仅可以归档文件,还可以对它们进行压缩以节省存储空间。一种常用的压缩格式是 gunzip
,其扩展名通常为 .tar.gz
或 .tgz
。我们可以使用 z
选项来指定使用 gunzip
压缩文件。 示例如下:
$ tar cvzf archive.tar.gz file* file1.txt file2.txt file3.txt $ ls -l archive.tar archive.tar.gz -rw-r--r-- 1 abhisheknair abhisheknair 10240 Sep 12 20:15 archive.tar -rw-r--r-- 1 abhisheknair abhisheknair 188 Sep 12 20:21 archive.tar.gz $
可以观察到,即使两个归档文件都包含了相同的三个文件,它们的大小却有明显的差异。这是因为使用了 z
选项进行了压缩。
创建压缩归档(BZ2 格式)
tar
还支持其他几种压缩格式,例如 bz2
或 bzip2
,其扩展名通常为 .tar.bz2
或 .tbz2
。 这种格式可能会产生更小的归档文件,但代价是会消耗更多的 CPU 资源,导致压缩和解压缩过程比 gz
格式慢。
示例如下:
$ tar cvjf archive.tar.bz2 file* file1.txt file2.txt file3.txt $ ls -l archive.tar archive.tar.gz archive.tar.bz2 -rw-r--r-- 1 abhisheknair abhisheknair 10240 Sep 12 20:15 archive.tar -rw-r--r-- 1 abhisheknair abhisheknair 212 Sep 12 20:25 archive.tar.bz2 -rw-r--r-- 1 abhisheknair abhisheknair 188 Sep 12 20:21 archive.tar.gz $ file archive.tar* archive.tar: POSIX tar archive (GNU) archive.tar.bz2: bzip2 compressed data, block size = 900k archive.tar.gz: gzip compressed data, from Unix, original size modulo 2^32 10240 $
解压所有文件
要解压 tar
归档文件,无论是压缩的还是未压缩的,都可以简单地使用 x
选项。以下示例演示了其用法:
$ tar xvf archive.tar file1.txt file2.txt file3.txt $ ls -l total 24 -rw-r--r-- 1 abhisheknair abhisheknair 10240 Sep 19 18:25 archive.tar -rw-r--r-- 1 abhisheknair abhisheknair 13 Sep 12 20:08 file1.txt -rw-r--r-- 1 abhisheknair abhisheknair 19 Sep 12 20:08 file2.txt -rw-r--r-- 1 abhisheknair abhisheknair 24 Sep 12 20:08 file3.txt $
此方法同样适用于 gz
压缩的归档文件:
$ tar xvf archive.tar.gz file1.txt file2.txt file3.txt $ ls -l total 16 -rw-r--r-- 1 abhisheknair abhisheknair 188 Sep 19 18:27 archive.tar.gz -rw-r--r-- 1 abhisheknair abhisheknair 13 Sep 12 20:08 file1.txt -rw-r--r-- 1 abhisheknair abhisheknair 19 Sep 12 20:08 file2.txt -rw-r--r-- 1 abhisheknair abhisheknair 24 Sep 12 20:08 file3.txt $
以及 bz2
压缩的归档文件:
$ tar xvf archive.tar.bz2 file1.txt file2.txt file3.txt $ ls -l total 16 -rw-r--r-- 1 abhisheknair abhisheknair 212 Sep 19 18:31 archive.tar.bz2 -rw-r--r-- 1 abhisheknair abhisheknair 13 Sep 12 20:08 file1.txt -rw-r--r-- 1 abhisheknair abhisheknair 19 Sep 12 20:08 file2.txt -rw-r--r-- 1 abhisheknair abhisheknair 24 Sep 12 20:08 file3.txt $
列出 tar 文件内容
要列出 tar
归档文件的内容,可以使用 t
选项,如下所示:
$ tar tvf archive.tar.bz2 -rw-r--r-- abhisheknair/abhisheknair 13 2021-09-12 20:08 file1.txt -rw-r--r-- abhisheknair/abhisheknair 19 2021-09-12 20:08 file2.txt -rw-r--r-- abhisheknair/abhisheknair 24 2021-09-12 20:08 file3.txt $
解压特定文件
可以通过指定文件名来解压 tar
归档中的特定文件:
$ tar xvf archive.tar.bz2 file1.txt file1.txt $ ls -l total 8 -rw-r--r-- 1 abhisheknair abhisheknair 212 Sep 19 18:31 archive.tar.bz2 -rw-r--r-- 1 abhisheknair abhisheknair 13 Sep 12 20:08 file1.txt $
同样,可以指定多个文件名(以空格分隔)来同时解压它们。
$ tar xvf archive.tar.bz2 file1.txt file3.txt file1.txt file3.txt $ ls -l total 12 -rw-r--r-- 1 abhisheknair abhisheknair 212 Sep 19 18:31 archive.tar.bz2 -rw-r--r-- 1 abhisheknair abhisheknair 13 Sep 12 20:08 file1.txt -rw-r--r-- 1 abhisheknair abhisheknair 24 Sep 12 20:08 file3.txt $
使用通配符解压
要使用通配符模式来提取一个或多个文件,请使用 --wildcards
选项:
$ tar xvf archive.tar.bz2 --wildcards "file*" file1.txt file2.txt file3.txt $ ls -l total 16 -rw-r--r-- 1 abhisheknair abhisheknair 212 Sep 19 18:31 archive.tar.bz2 -rw-r--r-- 1 abhisheknair abhisheknair 13 Sep 12 20:08 file1.txt -rw-r--r-- 1 abhisheknair abhisheknair 19 Sep 12 20:08 file2.txt -rw-r--r-- 1 abhisheknair abhisheknair 24 Sep 12 20:08 file3.txt $
向归档添加文件
可以使用 r
或 --append
选项,配合新的文件名或通配符模式,将新文件添加到现有的未压缩 tar
文件中(请注意,这仅适用于未压缩的 .tar
文件,不适用于 tar.gz
或 tar.bz2
等压缩格式):
$ tar rvf archive.tar file-new* file-new.txt file-new2.txt $ tar tvf archive.tar -rw-r--r-- abhisheknair/abhisheknair 13 2021-09-12 20:08 file1.txt -rw-r--r-- abhisheknair/abhisheknair 19 2021-09-12 20:08 file2.txt -rw-r--r-- abhisheknair/abhisheknair 24 2021-09-12 20:08 file3.txt -rw-r--r-- abhisheknair/abhisheknair 15 2021-09-19 18:59 file2.txt -rw-r--r-- abhisheknair/abhisheknair 10 2021-09-19 18:58 file4.txt -rw-r--r-- abhisheknair/abhisheknair 9 2021-09-19 19:10 file-new.txt -rw-r--r-- abhisheknair/abhisheknair 9 2021-09-19 19:10 file-new2.txt $
可以观察到,archive.tar
的列表内容中新增了两个文件。
从归档中删除文件
可以使用 --delete
选项从 tar
归档文件中删除特定文件,如下所示(比较删除文件前后 tar
文件的列表):
$ tar tvf archive.tar -rw-r--r-- abhisheknair/abhisheknair 13 2021-09-12 20:08 file1.txt -rw-r--r-- abhisheknair/abhisheknair 19 2021-09-12 20:08 file2.txt -rw-r--r-- abhisheknair/abhisheknair 24 2021-09-12 20:08 file3.txt -rw-r--r-- abhisheknair/abhisheknair 15 2021-09-19 18:59 file2.txt -rw-r--r-- abhisheknair/abhisheknair 10 2021-09-19 18:58 file4.txt -rw-r--r-- abhisheknair/abhisheknair 9 2021-09-19 19:10 file-new.txt -rw-r--r-- abhisheknair/abhisheknair 9 2021-09-19 19:10 file-new2.txt $ tar --delete -f archive.tar file-new.txt file-new2.txt $ tar tvf archive.tar -rw-r--r-- abhisheknair/abhisheknair 13 2021-09-12 20:08 file1.txt -rw-r--r-- abhisheknair/abhisheknair 19 2021-09-12 20:08 file2.txt -rw-r--r-- abhisheknair/abhisheknair 24 2021-09-12 20:08 file3.txt -rw-r--r-- abhisheknair/abhisheknair 15 2021-09-19 18:59 file2.txt -rw-r--r-- abhisheknair/abhisheknair 10 2021-09-19 18:58 file4.txt $
同样,此操作仅适用于未压缩的 tar
文件,对于压缩的归档格式将失败。
创建并验证
在创建未压缩的 tar
文件时,可以使用 W
选项来验证归档文件的内容:
$ tar cvfW archive.tar file*.txt file1.txt file2.txt file3.txt Verify file1.txt Verify file2.txt Verify file3.txt $
此选项不能与压缩选项一起使用,但你可以在之后使用 gzip
或其他工具来压缩创建的 tar
文件。
解压 tar 到指定文件夹
如果希望将 tar
归档文件的内容解压到指定文件夹,而不是当前目录,可以使用 -C
选项和目录路径,如下所示:
$ tar xvf archive.tar -C new-directory/ file1.txt file2.txt file3.txt file2.txt file4.txt $ ls -l new-directory/ total 16 -rw-r--r-- 1 abhisheknair abhisheknair 13 Sep 12 20:08 file1.txt -rw-r--r-- 1 abhisheknair abhisheknair 15 Sep 19 18:59 file2.txt -rw-r--r-- 1 abhisheknair abhisheknair 24 Sep 12 20:08 file3.txt -rw-r--r-- 1 abhisheknair abhisheknair 10 Sep 19 18:58 file4.txt $
使用差异选项
可以使用 --diff
或 d
选项来查找 tar
归档文件中的文件与文件系统中的文件之间的差异。以下示例展示了当 tar
内部和外部的文件相同时运行差异检测。更新文件后,再次运行以查看输出差异。
$ tar dvf archive.tar file4.txt file4.txt $ $ echo newline > file4.txt $ $ tar dvf archive.tar file4.txt file4.txt file4.txt: Mod time differs file4.txt: Size differs $
排除文件
在创建 tar
归档文件时,可能需要排除某些特定文件。 可以通过 --exclude
选项来实现。
$ tar --exclude="dir/file2.txt" --exclude="dir/file-new*.txt" -cvzf archive.tar.gz dir/ dir/ dir/file1.txt dir/file3.txt $ ls -l dir total 24 -rw-r--r-- 1 abhisheknair abhisheknair 9 Sep 19 19:10 file-new.txt -rw-r--r-- 1 abhisheknair abhisheknair 9 Sep 19 19:10 file-new2.txt -rw-r--r-- 1 abhisheknair abhisheknair 5 Sep 19 19:20 file-new3.txt -rw-r--r-- 1 abhisheknair abhisheknair 5 Sep 19 19:27 file1.txt -rw-r--r-- 1 abhisheknair abhisheknair 6 Sep 19 19:27 file2.txt -rw-r--r-- 1 abhisheknair abhisheknair 8 Sep 19 19:27 file3.txt $ tar tvf archive.tar.gz drwxr-xr-x abhisheknair/abhisheknair 0 2021-09-19 19:30 dir/ -rw-r--r-- abhisheknair/abhisheknair 5 2021-09-19 19:27 dir/file1.txt -rw-r--r-- abhisheknair/abhisheknair 8 2021-09-19 19:27 dir/file3.txt $
从以上输出可以看出,我们可以多次指定 --exclude
选项,从而在 AND 条件下指定多个文件名或模式。请注意,在上述示例中,目录中的六个文件中,只有两个文件符合包含在 archive.at.gz
中的条件。
查看 tar 内容大小
我们可以使用以下命令获取压缩的 tar
归档文件内容的大小:
$ tar tvf archive.tar.gz -rw-r--r-- abhisheknair/abhisheknair 13 2021-09-12 20:08 file1.txt -rw-r--r-- abhisheknair/abhisheknair 19 2021-09-12 20:08 file2.txt -rw-r--r-- abhisheknair/abhisheknair 24 2021-09-12 20:08 file3.txt $ tar -xzf archive.tar.gz --to-stdout|wc -c 56 $
同样适用于 bz2
归档:
$ tar tvf archive.tar.bz2 -rw-r--r-- abhisheknair/abhisheknair 13 2021-09-12 20:08 file1.txt -rw-r--r-- abhisheknair/abhisheknair 19 2021-09-12 20:08 file2.txt -rw-r--r-- abhisheknair/abhisheknair 24 2021-09-12 20:08 file3.txt $ tar -xjf archive.tar.bz2 --to-stdout|wc -c 56 $
保留权限
默认情况下,tar
命令会保留正在归档的文件和目录的权限,尽管可以使用 -p
选项或 --preserve-permissions
来明确指定此行为,如下所示:
$ tar cvpzf archive.tar.gz *.txt file1.txt file2.txt file3.txt $
总结
tar
长期以来一直是 Unix/Linux 系统中的实用工具,主要用于文件归档和备份任务。随着时间的推移,此工具已经发展出许多选项。如果您了解它提供的功能,它可以用于简单到复杂的任务。本文介绍了使用 tar
命令执行的一些基本操作,并演示了它如何帮助您完成日常系统管理任务。
要获取更多详细信息,请参阅其手册页 (man tar
) 或使用 tar --help
或 tar --usage
命令。