我一直很好奇:作为一个文件打包的格式,tar 包为什么在解压后,使用 ls -l 命令查看,文件的许可权、文件 owner 和 group、修改时间等等各种属性都在? 除了正常的文件,连设备文件也可以打包,因为如此,tar 命令可以用来备份整个 Linux 操作系统,一旦玩崩了,用备份恢复,什么都不会丢。

tar 命令是 Unix/Linux 平台用的最多的命令之一。 原始的 tar 只具备打包和解包的功能, Tape ARchive, 本义就是把文件打包备份到磁带机。 GNU 为 tar 增加了很多新功能,比如支持各种压缩格式。本文只讨论原始的 tar,它只打包而不做压缩。

我搜索到了 GNU tar 的官网文档,在看到了 TAR 文件的格式定义后,一切全明白了。

Basic Tar Format?

www.gnu.org

在 Unix 中一切都是文件:普通文件,文件夹,符号链接,设备文件等等。tar 包就是由一个个文件顺序排列而成,每个文件由两部分组成:文件头和文件内容。

文件头的格式用C语言结构体定义如下:

struct posix_header
{ /* byte offset */
char name[100]; /* 0 */ 文件名
char mode[8]; /* 100 */ 用户许可权
char uid[8]; /* 108 */ user id
char gid[8]; /* 116 */ group id
char size[12]; /* 124 */ 文件大小
char mtime[12]; /* 136 */ 修改时间
char chksum[8]; /* 148 */ 校验值
char typeflag; /* 156 */ 文件类型标志
char linkname[100]; /* 157 */ 符号链接指向
char magic[6]; /* 257 */
char version[2]; /* 263 */
char uname[32]; /* 265 */ user name
char gname[32]; /* 297 */ group name
char devmajor[8]; /* 329 */ 设备文件 major
char devminor[8]; /* 337 */ 设备文件 minor
char prefix[155]; /* 345 */
/* 500 */
};

文件类型标志定义,包含了所有 Unix 系统中的文件类型

#define REGTYPE 0 /* regular file */
#define LNKTYPE 1 /* link */
#define SYMTYPE 2 /* reserved */
#define CHRTYPE 3 /* character special */
#define BLKTYPE 4 /* block special */
#define DIRTYPE 5 /* directory */
#define FIFOTYPE 6 /* FIFO special */
#define CONTTYPE 7 /* reserved */

可以看到,文件头里面包含了很丰富的信息,tar 为啥能够打包各种文件格式,已经不言自明。

值得一提的是,在解包时,应该用 root 身份,否则文件的 uid 和 gid 等会修改为当前的用户 id。


推荐阅读:
相关文章