跳至内容

tar 命令

概述

tar 是一个用于在 GNU/Linux 和其他 UNIX 操作系统上处理归档文件的工具。它代表“磁带归档”(tape archive)。

最初,tar 归档的用途是将文件方便地存储在磁带上。 “tar” 的名称也由此而来。尽管该实用程序名为 tar,但 tar 可以将其输出定向到可用设备、文件或其他程序(使用管道),并访问远程设备或文件(作为归档)。

现代 GNU/Linux 上使用的 tar 最初来自 GNU 项目。你可以在 GNU 网站 上浏览和下载所有版本的 tar

注意

不同发行版中的 tar 可能具有不同的默认选项。使用时请务必小心。

# RockyLinux 8 and Fedora 41
Shell > tar --show-defaults
--format=gnu -f- -b20 --quoting-style=escape --rmt-command=/etc/rmt --rsh-command=/usr/bin/ssh

使用 tar

使用 tar 时,请注意它有两种保存模式:

  • 相对模式(默认):删除文件开头的 “/” 字符。即使你使用绝对路径添加文件,tar 在此模式下也会删除开头的 “/” 字符。
  • 绝对模式:保留开头的 “/” 字符并将其包含在文件名中。你需要使用 -P 选项来启用此保存模式。在此模式下,你必须将所有文件表示为绝对路径。出于安全原因,在大多数情况下不应使用此保存模式,除非有特殊场景需求。

当你使用 tar 时,会遇到诸如 .tar.gz.tar.xz.tar.bz2 之类的后缀,这表明你首先创建了一个归档(将相关文件归类为单个文件),然后使用相关的压缩类型或算法对文件进行压缩。

压缩类型或算法可以是 gzip、bzip2、xz、zstd 或其他。

tar 允许从备份中提取单个文件或目录、查看其内容或验证其完整性。

创建归档并使用压缩的用法是:

  • tar [选项] [路径] [目录1] ... [文件1] ...。例如:tar -czvf /tmp/Fullbackup-20241201.tar.gz /etc/ /var/log/

从归档中提取文件的用法是:

  • tar [选项] [路径] -C [目录]。例如:tar -xzvf /tmp/Fullbackup-20241201.tar.gz -C /tmp/D1

技巧

当你从归档文件中提取文件时,tar 会根据手动添加的后缀自动选择压缩类型。例如,对于 .tar.gz 文件,你可以直接使用 tar -vxf 而无需使用 tar -zvxf。在创建归档压缩文件时,你必须选择压缩类型。

注意

在 GNU/Linux 中,大多数文件不需要扩展名,除了桌面环境(GUI)。人为添加后缀是为了方便人类用户识别。例如,如果系统管理员看到 .tar.gz.tgz 文件扩展名,他就会知道如何处理该文件。

操作参数或类型

类型 描述
-A 将一个归档中的所有文件追加到另一个归档的末尾。仅适用于归档非压缩的 .tar 类型文件。
-c 创建归档。非常常用。
-d 比较归档文件和对应的未归档文件之间的差异。
-r 将文件或目录追加到归档的末尾。仅适用于归档非压缩的 .tar 类型文件。
-t 列出归档的内容。
-u 仅将较新的文件追加到归档。仅适用于归档非压缩的 .tar 类型文件。
-x 从归档中提取。非常常用。
--delete 从 “.tar” 归档中删除文件或目录。仅适用于归档非压缩的 .tar 类型文件。

技巧

作者建议保留前缀 “-” 以保持用户对操作类型的习惯。这是可选的。这里的操作参数表示你对 tar 的主要功能。换句话说,你需要从上述类型中选择一个。

常用辅助选项

选项 描述
-z 使用 gzip 作为压缩类型。创建归档和从归档提取都适用。
-v 显示详细的处理信息。
-f 指定归档的文件名(包括文件后缀)。
-j 使用 bzip2 作为压缩类型。创建归档和从归档提取都适用。
-J 使用 xz 作为压缩类型。创建归档和从归档提取都适用。
-C 从归档中提取文件后的保存位置。
-P 使用绝对模式保存。

对于未提及的其他辅助选项,请参阅 man 1 tar

版本差异

在某些旧版本的 tar 中,选项被称为 “key(s)”,这意味着使用带 “-” 前缀的选项可能会导致 tar 无法按预期工作。此时,你需要删除 “-” 前缀才能使其正常工作。

选项样式说明

tar 提供三种选项样式:

  1. 传统样式

    • tar {A|c|d|r|t|u|x}[GnSkUWOmpsMBiajJzZhPlRvwo] [ARG...].
  2. 短选项样式的用法是:

    • tar -A [选项] 归档 归档
    • tar -c [-f 归档] [选项] [文件...]
    • tar -d [-f 归档] [选项] [文件...]
    • tar -t [-f 归档] [选项] [成员...]
    • tar -r [-f 归档] [选项] [文件...]
    • tar -u [-f 归档] [选项] [文件...]
    • tar -x [-f 归档] [选项] [成员...]
  3. 长选项样式的用法是:

    • tar {--catenate|--concatenate} [选项] 归档 归档
    • tar --create [--file 归档] [选项] [文件...]
    • tar {--diff|--compare} [--file 归档] [选项] [文件...]
    • tar --delete [--file 归档] [选项] [成员...]
    • tar --append [-f 归档] [选项] [文件...]
    • tar --list [-f 归档] [选项] [成员...]
    • tar --test-label [--file 归档] [选项] [标签...]
    • tar --update [--file 归档] [选项] [文件...]
    • tar --update [-f 归档] [选项] [文件...]
    • tar {--extract|--get} [-f 归档] [选项] [成员...]

第二种方法是大多数 GNU/Linux 用户更常用的。

压缩效率和使用频率

tar 本身不具备压缩能力,因此你必须与其他压缩工具一起使用。压缩和解压缩会影响资源消耗。

以下是针对一组文本文件,从效率最低到最高的压缩排名:

  • compress (.tar.Z) - 不太流行
  • gzip (.tar.gz.tgz) - 流行的
  • bzip2 (.tar.bz2.tb2.tbz) - 流行的
  • lzip (.tar.lz) - 不太流行
  • xz (.tar.xz) - 流行的

tar 的命名约定

以下是 tar 归档命名约定的一些示例:

主要功能和辅助选项 文件 后缀 功能
-cvf home home.tar 相对模式下的 /home,未压缩形式。
-cvfP /etc etc.A.tar 绝对模式下的 /etc,无压缩。
-cvfz usr usr.tar.gz 相对模式下的 /usrgzip 压缩。
-cvfj usr usr.tar.bz2 相对模式下的 /usrbzip2 压缩。
-cvfPz /home home.A.tar.gz 绝对模式下的 /homegzip 压缩。
-cvfPj /home home.A.tar.bz2 绝对模式下的 /homebzip2 压缩。

你也可以在文件名中添加日期。

使用示例

-c 类型

  1. 以相对模式归档并压缩 /etc/,后缀为 .tar.gz

    Shell > tar -czvf /tmp/etc-20241207.tar.gz /etc/
    

    由于 tar 默认以相对模式工作,命令输出的第一行将显示以下内容:

    tar: Removing leading '/' from member names
    
  2. 归档 /var/log/ 并选择 xz 类型进行压缩。

    Shell > tar -cJvf /tmp/log-20241207.tar.xz /var/log/
    
    Shell > du -sh /var/log/ ; ls -lh /tmp/log-20241207.tar.xz
    18M     /var/log/
    -rw-r--r-- 1 root root 744K Dec  7 14:40 /tmp/log-20241207.tar.xz
    
  3. 在不生成归档的情况下估算文件大小。

    Shell > tar -cJf - /etc | wc -c
    tar: Removing leading `/' from member names
    3721884
    

    wc -c 命令的输出单位是字节。

  4. 分割大型 .tar.gz 文件。

    Shell > cd /tmp/ ; tar -czf - /etc/  | split -d -b 2M - etc-backup20241207.tar.gz.
    
    Shell > ls -lh /tmp/
    -rw-r--r-- 1 root root 2.0M Dec  7 20:46 etc-backup20241207.tar.gz.00
    -rw-r--r-- 1 root root 2.0M Dec  7 20:46 etc-backup20241207.tar.gz.01
    -rw-r--r-- 1 root root 2.0M Dec  7 20:46 etc-backup20241207.tar.gz.02
    -rw-r--r-- 1 root root  70K Dec  7 20:46 etc-backup20241207.tar.gz.03
    

    第一个 “-” 代表 tar 的输入参数,而第二个 “-” 表示 tar 将输出重定向到 stdout

    要提取这些分割后的小文件,你可以执行以下操作:

    Shell > cd /tmp/ ; cat etc-backup20241207.tar.gz.* >> /tmp/etc-backup-20241207.tar.gz
    
    Shell > cd /tmp/ ; tar -xvf etc-backup-20241207.tar.gz -C /tmp/dir1/
    

-x 类型

  1. 下载 Redis 源代码并将其提取到 /usr/local/src/ 目录:

    Shell > wget -c https://github.com/redis/redis/archive/refs/tags/7.4.1.tar.gz
    
    Shell > tar -xvf 7.4.1.tar.gz -C /usr/local/src/
    
  2. 仅从归档 zip 文件中提取一个文件。

    Shell > tar -xvf /tmp/etc-20241207.tar.gz etc/chrony.conf
    

-A-r 类型

  1. 将一个 .tar 文件追加到另一个 .tar 文件末尾。

    Shell > tar -cvf /tmp/etc.tar /etc/
    
    Shell > tar -cvf /tmp/log.tar /var/log/
    
    Shell > tar -Avf /tmp/etc.tar /tmp/log.tar
    

    这意味着 “log.tar” 中的所有文件都将追加到 “etc.tar” 的末尾。

  2. 将文件或目录追加到 .tar 文件末尾。

    Shell > tar -rvf /tmp/log.tar /etc/chrony.conf
    tar: Removing leading `/' from member names
    /etc/chrony.conf
    tar: Removing leading `/' from hard link targets
    
    Shell > tar -rvf /tmp/log.tar /tmp/dir1
    

警告

无论你使用 -A 还是 -r 选项,都要考虑相关归档文件的保存模式。

警告

-A-r 不适用于归档压缩文件。

-t 类型

  1. 查看归档的内容。

    Shell > tar -tvf /tmp/log.tar
    
    Shell > tar -tvf /tmp/etc-20241207.tar.gz | less
    

-d 类型

  1. 比较文件差异。

    Shell > cd / ; tar -dvf /tmp/etc.tar etc/chrony.conf
    etc/chrony.conf
    
    Shell > cd / ; tar -dvf /tmp/etc-20241207.tar.gz etc/
    

    对于使用相对模式的存储方法,在使用 -d 类型时,将文件路径切换到 “/”。

-u 类型

  1. 如果同一文件有多个版本,你可以使用 -u 类型。

    Shell > touch /tmp/tmpfile1
    
    Shell > tar -rvf /tmp/log.tar /tmp/tmpfile1
    
    Shell > echo "File Name" >> /tmp/tmpfile1
    
    Shell > tar -uvf /tmp/log.tar /tmp/tmpfile1
    
    Shell > tar -tvf /tmp/log.tar
    ...
    -rw-r--r-- root/root         0 2024-12-07 18:53 tmp/tmpfile1
    -rw-r--r-- root/root        10 2024-12-07 18:54 tmp/tmpfile1
    

--delete 类型

  1. 你也可以使用 --delete.tar 文件中删除文件。

    Shell > tar --delete -vf /tmp/log.tar tmp/tmpfile1
    
    Shell > tar --delete -vf /tmp/etc.tar etc/motd.d/
    

    删除时,你将从归档中删除所有同名文件。

常用术语

一些网站提到了两个术语:

  • tarfile - 指的是未压缩的归档文件,例如 .tar 文件。
  • tarball - 指的是压缩的归档文件,例如 .tar.gz.tar.xz

作者:李天赐

贡献者:Ganna Zhyrnova, Steven Spencer