系统管理员和开发人员的 15 个 tar 命令示例

深入理解 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 还支持其他几种压缩格式,例如 bz2bzip2,其扩展名通常为 .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.gztar.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
$

使用差异选项

可以使用 --diffd 选项来查找 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 --helptar --usage 命令。