Linux中tar命令简介
1. 概述
当我们想要在不同的 Linux 系统之间传输多个文件时,将它们打包成一个存档通常是个好主意。
如果我们考虑归档和通用文件打包,磁带归档 ( *tar)*是大多数 Linux 系统上的事实标准。
在本快速教程中,我们将学习如何使用tar 实用程序来操作此类存档。
2. 语法
我们先来看看基本语法:
$ tar {operation} [options...] [file]...
默认情况下,我们至少需要指定一个操作。默认选项和输入取决于操作类型。我们将分别介绍这些内容。
在 Linux 中,一切皆文件。这意味着我们还可以归档文件的目录结构。
由于历史原因,** tar接受各种格式的操作**:
- 以破折号开头的 UNIX 短格式
- GNU 长格式,前面有两个破折号
- 不使用破折号的旧样式格式
我们的大多数示例都使用 UNIX 风格的格式。但是,我们还需要一些 GNU 选项。
3. 基本操作
大多数时候,我们只需要三个基本操作:
- 创建存档
- 提取存档
- 列出档案
让我们仔细看看每一个。
3.1. 创建档案
让我们使用*-c*标志创建一个由两个文件组成的存档:
$ tar -c -f archive.tar file1 file2
$ ls
archive.tar file1 file2
在此示例中,我们还使用*-f*选项定义了输出存档文件。
如果我们不指定输出文件,则默认行为是使用 TAPE环境变量中定义的内容或已编译的默认值。
在大多数情况下,它会尝试使用标准输出流。这将产生一个错误,除非我们将输出 重定向到一个文件:
$ tar -c file1 file2 > archive.tar
$ ls
archive.tar file1 file2
现在让我们假设我们有两个文件在一个名为test的文件夹中:
$ ls -alh test
-rw-r--r-- 1 user users 6 Mar 20 23:19 file1
-rw-r--r-- 1 user users 12 Mar 20 23:19 file2
$ tar -c -f folder.tar test
$ ls -allh
-rw-r--r-- 1 user users 10K Mar 20 23:19 folder.tar
drwxr-xr-x 2 user users 4.0K Mar 20 23:19 test
默认情况下,tar递归地归档文件夹。因此,存档还将包含父目录和两个文件。
3.2. 提取档案
现在我们已经了解了如何创建存档,让我们来看看如何提取存档。
我们可以使用*-x标志指示tar*提取存档:
$ tar -x -f archive.tar
$ ls -allh
-rw-r--r-- 1 user users 10K Mar 20 22:51 archive.tar
-rw-r--r-- 1 user users 6 Mar 18 20:54 file1
-rw-r--r-- 1 user users 12 Mar 18 20:54 file2
默认行为是覆盖具有相同名称的现有文件系统文件。
请注意,我们再次使用*-f*选项来指定要提取的存档。
同样,我们可以通过将存档重定向到tar的标准输入流来省略它:
$ tar -x < archive.tar
这给了我们相同的结果。
我们还可以只提取存档的特定成员:
$ tar -x -f archive.tar file2
$ ls -allh
-rw-r--r-- 1 user users 10K Mar 20 22:51 archive.tar
-rw-r--r-- 1 user users 12 Mar 18 20:54 file2
这里有一个潜在的问题。还记得我们在上一节中归档文件夹吗?
在这种情况下,我们需要指定文件的完全限定名称:
$ tar -x -f folder.tar test/file2
$ ls -allh
-rw-r--r-- 1 user users 10K Mar 20 23:30 folder.tar
drwxr-xr-x 2 user users 4.0K Mar 20 23:31 test
$ ls -allh test
-rw-r--r-- 1 user users 12 Mar 20 23:19 file2
结果也有点出乎意料。注意,我们还将test文件夹提取到放置file2 的位置。
3.3. 上市档案
有时我们不想提取存档,而只是看一下它的内容。这就是列表选项的用途。
我们可以再次结合使用*-t选项和-f*来打印存档的内容:
$ tar -t -f archive.tar
file1
file2
同样,我们也可以使用重定向:
$ tar -t < archive.tar
file1
file2
现在让我们看一下前面示例中的folder存档:
$ tar -t -f folder.tar
test/
test/file1
test/file2
同样,我们也可以指定列出哪些文件或文件夹:
$ tar -t -f folder.tar test/file1
test/file1
4.高级操作
现在让我们看一下更高级的示例。
4.1. 更新档案
在某些情况下,我们希望将新文件添加到现有存档中。
幸运的是,我们可以使用带有-u选项的tar**。还记得我们的第一个存档有两个文件吗?
现在让我们添加第三个:
$ tar -t -f archive.tar
file1
file2
$ tar -u -f archive.tar file3
$ tar -t -f archive.tar
file1
file2
file3
我们还可以用更新的版本更新现有的存档成员。如果tar为我们的文件检测到更新的修改日期,它会将其添加到存档中。
我们修改file3的内容,重新添加:
$ tar -u -f archive.tar file3
$ tar -t -f archive.tar
file1
file2
file3
file3
这里发生了什么?现在我们的存档中有两个file3实例。
更新不会替换存档中的现有文件。相反,新修改的文件被添加到我们的档案中。
那么更新是如何工作的呢?当我们提取档案时,提取的顺序由我们归档的顺序给出。
这意味着 file3的第一个实例首先被提取,然后被file3的第二个(更新的)版本覆盖。
现在让我们尝试再次添加相同的文件而不修改它:
$ tar -u -f archive.tar file3
$ tar -t -f archive.tar
file1
file2
file3
file3
没有添加任何内容,因为tar根据修改日期检测到我们的文件没有更改。
4.2. 附加到档案
我们还可以使用*-r*选项附加到现有存档。
说到这里,我们可能会问 update 和 append 有什么区别。
与更新不同,当我们追加时,tar不关心修改日期。
现在让我们尝试追加而不是更新我们之前示例中使用的相同file3 :
$ tar -r -f archive.tar file3
$ tar -t -f archive.tar
file1
file2
file3
file3
file3
请注意,我们现在在存档中拥有同一文件的三个副本。让我们解释一下我们是如何结束这种情况的。
第一个实例是我们在第一次更新存档时添加的实例。 第二个是我们修改过的,然后用它再次更新存档。 第三个实例与第二个实例相同,我们只是将其附加到我们的存档中。请记住,更新是不可能的。
4.3. 串联档案
当我们想将现有档案合并为一个时,连接就派上用场了。
假设我们有包含测试文件的archive1.tar和archive2.tar :
$ tar -t -f archive1.tar
file1
file2
$ tar -t -f archive2.tar
file3
我们可以使用-A*标志*合并第一个存档中的所有内容:
$ tar -A -f archive1.tar archive2.tar
$ tar -t -f archive1.tar
file1
file2
file3
4.4. 从档案中删除成员
最后,在某些情况下,我们希望从存档中删除文件或文件夹。
让我们在前面的示例中使用此操作:
$ tar --delete -f archive1.tar file2
$ tar -t -f archive1.tar
file1
file3
请注意,与以前的选项不同,我们现在使用 GNU 长格式。那是因为我们没有一个简短的等价物。
最重要的是,我们在使用它时应该小心,因为它涉及重写整个存档,这可能是一个缓慢的过程。
5. 选项
到目前为止,我们已经看到了一些基本选项。当然,根据操作类型的不同,我们还可以使用更多 。
现在让我们玩一些最有趣的。
5.1. 压缩和解压
到目前为止,我们的档案只是一种对文件进行分组的方式。
让我们使用*-z*选项添加一些gzip 压缩:
$ tar -c -z -f compressed.tar.gz large1 large2
$ ls -allh
-rw-r--r-- 1 user users 31K Mar 18 23:38 compressed.tar.gz
-rw-r--r-- 1 user users 10M Mar 18 22:16 large1
-rw-r--r-- 1 user users 20M Mar 18 22:19 large2
-rw-r--r-- 1 user users 31M Mar 18 23:38 uncompressed.tar.gz
当然,大小的差异是惊人的,因为我们使用了一些虚拟文件。
像往常一样,我们总是可以查看tar手册以了解所有可能的压缩算法 。
提取压缩档案怎么样?我们像常规存档一样进行操作:
$ tar -x -f compressed.tar.gz
$ ls -allh
-rw-r--r-- 1 user users 31K Mar 20 23:34 compressed.tar.gz
-rw-r--r-- 1 user users 10M Mar 18 22:16 large1
-rw-r--r-- 1 user users 20M Mar 18 22:19 large2
tar命令在存档中使用一个特殊的元数据字节来描述压缩算法。
因此,我们不需要指定相应的解压选项。
不幸的是,缺点是我们无法以任何方式修改压缩档案。
5.2. *.tgz和*.tar.gz文件扩展名
我们已经了解到可以使用tar命令的*-z选项来压缩 tarball。通常,我们会使用.tar.gz*扩展名来命名存档文件。但是,有时我们可以看到一些 *.tgz文件。
** .tgz和*.tar.gz扩展名都告诉我们文件是gzip压缩的 tarball。可以使用相同的tar*命令提取它们。因此,这两个扩展之间没有区别。**
我们可能会问,好吧,如果这两个扩展意味着同样的事情,为什么我们有两个扩展?让我们简单地解释一下。
如果我们回顾过去的DOS ,我们会注意到FAT 文件系统只支持8.3 文件名 方案。即在老版本的DOS和Windows系统中无法识别名为foo.tar.gz的文件。因此,我们有一个较短的文件扩展名“ tgz ”来表示双扩展名“ tar.gz ”,以便在 FAT 文件系统中识别gzip压缩的 tarball。
今天,所有现代文件系统都支持双文件扩展名。因此,我们通常将“ tar.gz ”作为 gzip压缩包的扩展名,以获得更详细的信息。
同样,对于*bzip2 *压缩的 tarball,我们有“ tar.bz2 ”扩展名。
5.3. 冗长
我们可以使用*-v*选项为所有操作启用更详细的输出。
让我们看一下压缩档案:
$ tar -t -v -f compressed.tar.gz
-rw-r--r-- user/users 10485760 2020-03-18 22:16 large1
-rw-r--r-- user/users 20971520 2020-03-18 22:19 large2
这为我们提供了有关存档内容的更多详细信息。
让我们回到我们的更新示例:
$ tar -t -v -f archive.tar
-rw-r--r-- user/users 10240 2020-03-21 18:55 file1
-rw-r--r-- user/users 12 2020-03-18 20:54 file2
-rw-r--r-- user/users 40 2020-03-22 19:46 file3
-rw-r--r-- user/users 48 2020-03-22 22:18 file3
我们现在可以看到文件的修改日期和大小。
当我们在存档中有文件夹时,此选项通常会派上用场。
5.4. 多卷档案
在便携式磁盘容量有限的时代,我们习惯于将档案分成多个卷。
我们可以指示tar以最大Nx1024字节的卷分块我们的存档,甚至指定自定义大小。
让我们创建一个最大卷大小为 8 MB 的多卷存档:
$ tar -c -M -L 8M -f archive1.tar large1 large2
Prepare volume #2 for ‘archive1.tar’ and hit return: n archive2.tar
Prepare volume #3 for ‘archive2.tar’ and hit return: n archive3.tar
Prepare volume #4 for ‘archive3.tar’ and hit return: n archive4.tar
$ ls -allh
-rw-r--r-- 1 user users 8.1M Mar 18 23:07 archive1.tar
-rw-r--r-- 1 user users 8.1M Mar 18 23:07 archive2.tar
-rw-r--r-- 1 user users 8.1M Mar 18 23:07 archive3.tar
-rw-r--r-- 1 user users 6.0M Mar 18 23:07 archive4.tar
-rw-r--r-- 1 user users 10M Mar 18 22:16 large1
-rw-r--r-- 1 user users 20M Mar 18 22:19 large2
我们使用**-M标志来指示我们想要一个多卷存档,然后我们使用*-L*选项指定卷大小**。
结果,tar以交互方式提示我们命名每个卷。我们通过指定 n 选项和相应的名称来实现。
这里要记住的一个重要方面是我们不能压缩多卷档案。
5.5. 文件选择
当我们对大量文件进行操作时,大多数时候,我们想要一种更有效的方式来包含或排除单个文件。
幸运的是,我们可以使用-T*选项从基于文件的列表中指定我们的输入*。
我们先来看看我们的文件列表:
$ cat input-files
file1
file2
file3
folder/file4
我们只需要确保将文件放在不同的行上。
现在让我们创建一个存档并查看其中的内容:
$ tar -c -f archive.tar -T input-files
$ tar -t -f archive.tar
file1
file2
file3
folder/file4
我们还可以在提取存档时使用列表选项。