6.2 用tar归档
tar
命令可以用来归档文件。不过,它最初是设计用来将数据存储在磁带上(tape archives, tar)。可以用tar
将多个文件和文件夹保存为单个文件,同时还能保留所有的文件属性,如所有者、权限等。由该命令创建的文件通常称为tarball。
6.2.1 预备知识
所有类UNIX操作系统都默认包含tar
命令。它的语法简单,并且文件格式具备可移植性。让我们来看看命令的用法。
tar
包含一个参数列表:A
、c
、d
、r
、u
、x
、f
和v
。其中每一个参数都可以依据不同的用途单独使用。
6.2.2 实战演练
按照下面的语法,用tar
对文件进行归档:
- $ tar -cf output.tar [SOURCES]
例如:
- $ tar -cf output.tar file1 file2 file3 folder1 ..
命令中的 -c
代表“创建文件”(creat file),-f
代表“指定文件名”(specify filename)。
我们可以使用文件名列表或者诸如 *.txt
这类通配符来指定文件夹和文件名作为SOURCES。
上面的命令将原文件归档为单个文件output.tar。
文件名必须紧跟在 -f
之后,并且应该是参数组中的最后一项(例如,-cvvf filename.tar
和 -tvvf filename.tar
)。
我们不能传递上百个文件或文件夹作为 tar
的参数,毕竟参数数量不是无限制的。如果有很多文件需要归档的话,使用追加(append)选项要更安全些。
6.2.3 补充知识
让我们再来看看tar
命令的其他特性。
- 向归档文件中添加文件
有时候,我们可能需要向已存在的归档文件再添加一些文件(其用例情境包括:当有成百上千个文件需要归档且这些文件又无法作为命令行参数在一行中指定时)。
追加选项:-r
要向已存在的归档文件添加一个文件,可以使用:
- $ tar -rvf original.tar new_file
用下面的方法列出归档文件中的内容:
- $ tar -tf archive.tar
- yy/lib64/
- yy/lib64/libfakeroot/
- yy/sbin/
如果需要在归档或列出归档内容的过程中获知更多细节,可以使用 -v
或 -vv
选项。它们统称为verbose(v),它们允许在终端中输出更详细的信息,借助verbose
,你能够打印诸如文件权限、所有者所属组、文件修改日期等细节。
例如:
- $ tar -tvvf archive.tar
- drwxr-xr-x slynux/slynux 0 2010-08-06 09:31 yy/
- drwxr-xr-x slynux/slynux 0 2010-08-06 09:39 yy/usr/
- drwxr-xr-x slynux/slynux 0 2010-08-06 09:31 yy/usr/lib64/
- 从归档文件中提取文件或文件夹
下面的命令将归档文件的内容提取到当前目录中:
- $ tar -xf archive.tar
选项-x
表示提取(exact)。
使用-x
时,tar
命令将归档文件中的内容提取到当前目录。我们也可以用选项-C
指定需要将文件提取到哪个目录:
- $ tar -xf archive.tar -C /path/to/extraction_directory
这个命令将归档文件的内容提取到指定目录中。它提取的是归档文件中的全部内容。我们可以通过将文件名指定为命令行参数来提取特定的文件:
- $ tar -xvf file.tar file1 file4
上面的命令只提取file1和file4,同时忽略掉其他文件。
- 在
tar
中使用stdin
和stdout
进行归档时,我们可以将stdout
指定为输出文件,这样另一个命令就可以通过管道将它作为stdin
,并进行其他处理或提取内容。
当通过安全shell(Secure Shell,SSH)连接传输数据时,这招很管用。例如:
- $ mkdir ~/destination
- $ tar -cf - file1 file2 file3 | tar -xvf - -C ~/destination
在上面的例子中,首先对file1、file2和file3进行归档,然后将它们提取到~/destination中。在这个命令中:
-f
指定stdout
作为归档文件(当使用-c
选项时)-f
指定stdin
用于提取内容(当使用-x
选项时)
- 拼接两个归档文件
我们可以用 -A
选项轻松地合并多个tar
文件。
假设我们现在有两个tar
文件:file1.tar和file2.tar。我们可以按照下面的方法将file2.tar的内容合并到file1.tar中:
- $ tar -Af file1.tar file2.tar
查看内容,验证操作是否成功:
- $ tar -tvf file1.tar
- 通过检查时间戳来更新归档文件中的内容
添加选项可以将指定的任意文件加入到归档文件中。如果同名文件已经存在,那么结果就是在归档文件中包含了两个同名的文件。我们可以用更新选项 -u
指明:只有比归档文件中的同名文件更新的时候才进行添加。
- $ tar -tf archive.tar
- filea
- fileb
- filec
上面的命令将列出归档文件中的内容。
为了做到只有在filea
的文件内容修改时间更新(newer)的时候才对它进行添加,可以使用:
- $ tar -uvvf archive.tar filea
如果我们想要追加的filea
和归档文件中的filea
有相同的时间戳,那么不执行任何操作。
这时可用touch
命令修改文件的时间戳,然后再用tar
命令:
- $ tar -uvvf archive.tar filea
- -rw-r--r-- slynux/slynux 0 2010-08-14 17:53 filea
因为时间戳比归档文件中的同名文件更新,因此执行追加操作。
- 比较归档文件与文件系统中的内容
有时候,如果能够知道归档文件中的文件与文件系统中的同名文件是否有差别,对于我们而言还是有帮助的。选项 -d
可以打印出两者之间的差别:
- $ tar -df archive.tar filename1 filename2 ...
例如:
- $ tar -df archive.tar afile bfile
- afile: Mod time differs
- afile: Size differs
- 从归档文件中删除文件
我们可以用 --delete
选项从给定的归档文件中删除文件。例如:
- $ tar -f archive.tar --delete file1 file2 ..
来看另外一个例子:
- $ tar -tf archive.tar
- filea
- fileb
- filec
我们也可以使用下面的语法:
- $ tar --delete --file archive.tar [FILE LIST]
例如:
- $ tar --delete --file archive.tar filea
- $ tar -tf archive.tar
- fileb
- filec
- 压缩
tar
归档文件
tar
命令只能用来对文件进行归档,它并不具备压缩功能。出于这个原因,多数用户在使用归档文件时都会对文件采用某种形式的压缩,这样就能够大量降低文件的大小。归档文件通常被压缩成下列格式之一:
file.tar.gz
file.tar.bz2
file.tar.lzma
file.tar.lzo
不同的tar
选项可以用来指定不同的压缩格式。
-j
指定bunzip2格式;-z
指定gzip格式;--lzma
指定lzma格式。
这些格式会在随后专门讲解压缩的攻略中讨论。
可以不明确指定上面那些特定的选项来使用压缩功能。tar
可以通过查看输出或输入文件的扩展名来进行压缩。为了让tar
支持根据扩展名自动进行压缩,使用 -a
或 --auto-compress
选项。
- 从归档中排除部分文件
通过指定样式可以从归档中排除部分文件。用 --exclude [PATTERN]
排除匹配通配符样式的文件。
例如,排除所有的.txt文件:
- $ tar -cf arch.tar * --exclude "*.txt"
样式应该使用双引号来引用。
也可以将需要排除的文件列表放入文件中,同时配合选项 -X
:
- $ cat list
- filea
- fileb
- $ tar -cf arch.tar * -X list
这样就将filea
和fileb
从归档中排除了。
- 排除版本控制目录
我们通常使用tar
归档文件来分发源代码。大多数源代码都是使用版本控制系统进行维护,如subversion
、git
、mercurial
、cvs
等。版本控制系统中的代码目录包含用来管理版本的特殊目录,如.svn或.git。但源代码本身并不需要这些目录,所以不应该将它们包含在源代码的tar
归档文件中。
为了在归档时排除版本控制相关的文件和目录,可以使用tar的 --exclude-vcs
选项。例如:
- $ tar --exclude-vcs -czvvf source_code.tar.gz eye_of_gnome_svn
- 打印总字节数
有时候我们需要打印出归档了多少字节。用--totals
就可以在归档完成之后打印出总归档字节数:
- $ tar -cf arc.tar * --exclude "*.txt" --totals
- Total bytes written: 20480 (20KiB, 12MiB/s)
6.2.4 参考
6.4节讲解了
gzip
命令。6.5节讲解了
bzip2
命令。6.6节讲解了
lzma
命令。