1. 简介

tar 是 GNU 项目中的一个归档工具,其创建可以追溯到磁带机的年代,可谓历史悠久。虽然 tar 工具最初是用于磁带机的数据归档,但其现在也支持磁盘的数据归档,而且仍然保留着对磁带机的兼容。tar 工具一路发展过来,经过很多大佬的打磨,功能强大,现在已经是 Linux 系统上默认的数据归档工具。

需要注意的是,tar 只是一个归档工具,本身并不具有强大的压缩功能。不过可以通过给 tar 指定合适的选项,让其间接调用其它压缩工具来实现强大的压缩功能。

2. 格式

tar 工具的参数主要分为两种:

  • 操作:共有 8 个,用来指定具体执行什么操作。
  • 选项:用来在基础操作上,执行一些可选的扩展操作。

2.1 操作

操作 功能
-c--create 创建新的归档
-t--list 列出归档中的内容
-x--extract--get 提取归档中的内容
-r--append 追加内容到归档
-u--update 更新归档中的成员
-A--catenate--concatenate 拼接多个归档
-delete 删除归档中的成员
-d--compare--diff 对比归档中的成员和文件系统中的文件的区别

2.1.1 create

为三个文件 bluesfolkjazz 和一个文件夹 rock/ 归档:

1
tar -cvf collection.tar blues folk jazz rock/ # -cvf 为 -c,-v,-f 的缩写

2.1.2 list

查看归档 collection.tar 中的成员:

1
tar -tvf collection.tar     # -tvf 为 -t,-v,-f 的缩写

查看归档 collection.tar 中是否有 blues 成员名(匹配成员名是按照创建归档时存储的成员名严格进行的):

1
2
tar -tvf collection.tar blues       # 若有,则会输出对应成员名;否则报错
tar -tvf collection.tar --wildcards '*/blues' # 模糊匹配(当不确定完整成员名时)

2.1.3 extract

提取整个归档 collection.tar 中的成员:

1
tar -xvf collection.tar     # -xvf 为 -x,-v,-f 的缩写

提取归档 collection.tar 中的 blues 成员名:

1
2
tar -xvf collection.tar blues       # 严格匹配
tar -xvf collection.tar --wildcards '*/blues' # 模糊匹配

从归档中提取出来的成员,会按照它存储在归档中的路径名,在当前目录中创建对应路径。因此,如果只是想将文件提取到当前目录而忽略它在归档中存储的目录结构,可以使用 --strip-components 来指定跳过的目录级数:

1
tar -xvf collection.tar --strip-components=1 folk # 假设 folk 在 collection.tar 中的完整路径名为 ./folk

2.1.4 append

追加文件 rock 到已有归档文件 collection.tar 中:

1
tar -rvf collection.tar rock        # -rvf 是 -r,-v,-f 的缩写

需要注意的是,tar 允许往已有的归档文件中追加相同路径名的文件,而且它们都会保存在归档文件中,且它们会按照被加入归档的顺序在归档中有序存储。

  • 当使用 --extract 从归档中提取有很多相同路径名的成员时,最终得到的只有最后被加入归档的那个副本。
  • 这是因为 extract 操作提取归档成员是按照它们在归档中的存储顺序依次提取的,因此具有相同路径名的成员都将被提取出来,且在提取时排在后面的会覆盖前面的,而且这个覆盖过程在 tar 看来是正常的,因此它也不会有任提示。
  • 如果确实需要指定某个副本单独提取出来,则可以使用 --occurrence=n 选项指定只提取出出现第 nn 次的这个副本,即第 nn 个副本。

2.1.5 update

更新归档 collection.tar 中的成员 bluesjazz(假设 blues 修改了但 jazz 未修改):

1
tar -uvf collection.tar blues jazz  # -uvf 是 -u,-v,-f 的缩写

tar 首先会对比要更新的文件的修改时间,如果发现文件没有发生修改,就不会执行任何操作;如果发现文件发生了修改,就会将修改后的文件追加到归档中。

注意,是追加,不是替换。这是因为 tar 最初是为了写磁带机而创立的,而磁带的一个特点就是无论写还是读,都只能顺序操作。所以 tar 的更新操作只会将修改后的文件追加到归档文件中,同时原来的旧文件也仍然保存在归档文件中。

此外,如果要更新的文件在归档文件中没有,则 tar 会将这个新文件直接追加到归档文件中。

2.1.6 catenate

将归档文件 folkjazz.tar 拼接到归档文件 bluesrock.tar 中:

1
tar -Avf bluesrock.tar jazzfolk.tar # -Avf 是 -A,-u,-f 的缩写

需要注意的是,这些需要拼接的归档文件必须是兼容的格式,tar 不会去检查这些归档文件的格式,甚至不会去检查文件是不是归档文件。

2.1.7 delete

从归档文件 collection.tar 中移除 blues 文件:

1
tar --delete -vf collection.tar blues

注意,tar 会将归档中对应的所有相同成员名的成员删除。如果只想删除某一个具体的副本,则可以使用 --occurrence=n 选项指定只删除排在第 nn 个的这个副本。

2.1.8 compare

对比归档 collection.tar 中的成员 blues 和文件系统中具有相同路径名的文件之间的差异:

1
tar -dvf collection.tar blues

如果指定的归档成员在文件系统中不存在,则 tar 会警告;如果指定的归档成员不在归档中,则会报错。

2.2 常用选项

  • GNU tar 默认在归档时会省略掉成员的完整路径名最前面的 /..
  • GNU tar 默认会覆盖文件系统中相同路径名的文件。
选项 功能
-f archive-name--file=archive-name 指定归档文件的路径
-T file-files-from=file 指定包含在 file 中的所有归档路径作为 tar 的处理对象
-v--verbose 显示 tar 工具执行过程中的详细信息(此选项可多次指定,指定次数越多显示的信息越详细)
-w--interactive--confirmation 告诉 tar 当出现会破坏系统上的文件的操作时,通知用户是否执行而不是默认执行(比如同名文件覆盖)
--overwrite 显示表明在提取归档时覆盖同名文件
--overwrite-dir 显示表明在提取归档时覆盖同名文件夹
--show-stored-names 强制 tar 在创建归档并显示详细信息时,按照归档中的存储内容输出归档中成员的路径名
-O--to-stdout 结合 --extract 操作可以将成员提取并显示到标准输出
-P--absolute-names 阻止 GNU tar 在归档时会省略掉成员的完整路径名最前面的 /..
-a--auto-compress 根据归档包名的后缀自动识别压缩格式
--occurrence=n 指定处理相同成员名的第 nn 个副本
-h--dereference 归档时如果文件是符号链接,则追溯到原文件本身而不是归档链接文件
--hard-dereference 归档时如果文件是硬链接,则追溯到原文件本身而不是归档链接文件
--no-recursion 归档时不会递归到子目录下
--recursion 显示表明归档时要递归到子目录下
--sort=order 指定读取目录时处理其下面的文件顺序,order 可取值:nonenameinode
-C dir--directory=dir 当指定这个选项时,tar 会先切换到这个选项指定的目录下,然后再进行操作,并在操作完成后切换回来
--exclude=pattern 当指定这个选项时,tar 在归档时会忽略匹配模式的那些文件,匹配模式可使用 Shell 下的通配符,且最好用引号引起
-X file--exclude-from=file 在归档时忽略匹配文件 file 中罗列的那些模式的文件
-i--ignore-zeros 忽略归档文件中的 EOF 符
--mode=permissions 在归档时指定成员的权限(默认使用原文件的权限)
-o--no-same-owner 在归档时不保存成员的所有者(默认使用原文件的所有者)
--no-same-permissions 在归档时不保存成员的权限(默认使用原文件的权限)
-Z--compress--uncompress 指定 tar 在归档时使用 compress 程序进行压缩,以减小归档的大小
-j--bzip2 指定 tar 通过 bzip2 来读写归档
-z--gzip--gunzip--ungzip 指定 tar 在归档时使用 gzip 来读写归档
-lzip 指定 tar 在归档时使用 lzip 来读写归档
-lzma 指定 tar 在归档时使用 lzma 来读写归档
-lzop 指定 tar 在归档时使用 lzop 来读写归档
-J--xz 指定 tar 在归档时使用 xz 来读写归档
--zstd 指定 tar 在归档时使用 zstd 来读写归档

注意事项

  • 当使用 -c,--create 操作时,无论是否存在 -f,--file 指定的归档文件,tar 均会默认擦除其内容。即如果已经存在 -f,--file 指定的归档文件,tar 会默不作声地覆盖掉其中的内容。
  • 当使用 -x,--extract 操作时,如果提取到的当前目录包含和要提取出来的成员同名的文件(夹),则当前目录下的文件(夹)默认会被覆盖。因此,在提取归档时最好的做法是先检查一下归档中的成员,然后创建一个新的目录,在新创建的目录下提取归档。

3. 压缩 & 解压

tar 可以通过指定合适的选项,实现强大的压缩和解压功能。tar 目前支持的压缩程序有:gzip、bzip2、lzip、lzma、lzop、zstd、xz 以及传统的 compress。

压缩格式 长参数 短参数
gzip --gzip -z
bzip2 --bzip2 -j
xz --xz -J
lzip --lzip
lzma --lzma
lzop --lzop
zstd --zstd
compress --compress -Z

常用压缩包后缀及其对应的压缩程序:

后缀 压缩程序
.gz gzip
.tgz gzip
.taz gzip
.Z compress
.taZ compress
.bz2 bzip2
.tz2 bzip2
.tbz2 bzip2
.tbz bzip2
.lz lzip
.lzma lzma
.tlz lzma
.lzo lzop
.xz xz
.zst zstd
.tzst zstd

【注】在解压压缩包前,建议先用 tar -tvf 查看一下对应的压缩包,因为有些压缩包中的成员可能没有一个公共的根目录前缀,这个时候就要先手动创建一个目录,然后将压缩包解压到这个目录中。这样可以防止直接解压到当前目录下,造成当前目录的混乱。如果查看后发现其中的成员都有一个公共的根目录前缀,则可以放心解压到当前目录下。

常用压缩命令

1
2
3
4
5
6
7
8
9
tar -cvf tar_file xxx         # 创建 .tar 包
tar -czvf gzip_file xxx # 创建 .gz, .tgz. taz 包
tar -cjvf bzip2_file xxx # 创建 .bz2, .tz2, tbz2, .tbz 包
tar -cJvf xz_file xxx # 创建 .xz 包
tar -cZvf compress_file xxx # 创建 .Z, .taZ 包
tar --lzip -cvf lzip_file xxx # 创建 .lz 包
tar --lzma -cvf lzma_file xxx # 创建 .lzma, .tlz 包
tar --lzop -cvf lzop_file xxx # 创建 .lzo 包
tar --zstd -cvf zstd_file xxx # 创建 .zst, .tzst 包

常用解压命令

1
2
3
4
5
6
7
8
9
tar -xvf tar_file             # 提取 .tar 包
tar -xzvf gzip_file # 解压 .gz, .tgz. taz 包
tar -xjvf bzip2_file # 解压 .bz2, .tz2, tbz2, .tbz 包
tar -xJvf xz_file # 解压 .xz 包
tar -xZvf compress_file # 解压 .Z, .taZ 包
tar --lzip -xvf lzip_file # 解压 .lz 包
tar --lzma -xvf lzma_file # 解压 .lzma, .tlz 包
tar --lzop -xvf lzop_file # 解压 .lzo 包
tar --zstd -xvf zstd_file # 解压 .zst, .tzst 包

归档或提取归档时使用 -a/--auto-compress 选项,tar 会根据给出的归档文件后缀使用对应的压缩程序。

1
2
tar -cavf xxx_file yyy          # 压缩
tar -xavf xxx_file # 解压

附录

参考资料: