linux tar命令


gzip, bzip2和xz命令只能压缩单一文件,虽然可以对目录进行压缩,但是gzip, bzip2和xz命令是将目录内的所有文件分别进行压缩!
所以在用gzip, bzip2和xz压缩多个文件之前,需要将多个文件先打包成一个文件后再进行压缩。
tar命令可以先将多个目录或文件打包成一个大文件,然后通过gzip/bzip2/xz将该打包文件进行压缩!
一般将tar打包压缩后的文件称为tarball,例如file.tar.bz2,只打包但是没有压缩的文件称为tarfile,例如file.tar。
tar命令经常用于系统中重要文件目录的备份。
鉴于tar的广泛使用,Windows下的WinRAR也支持.tar.gz文件的解压缩!

1.tar命令

回到顶部
tar的常用选项与参数如下:
            [peter@study ~]$ tar [-z|-j|-J] [cv] [-f 待建立的新文件名] filename...     #打包与压缩
            [peter@study ~]$ tar [-z|-j|-J] [tv] [-f 既有的 tar 文件名]               #察看文件名
            [peter@study ~]$ tar [-z|-j|-J] [xv] [-f 既有的 tar 文件名] [-C 目录]      #解压缩
            
选项与参数:
-c :建立打包文件,可搭配-v来察看过程中被打包的文件名(filename)
-t :察看打包文件的内容含有哪些文件名,重点在察看文件名;
-x :解打包或解压缩的功能,可以搭配-C(大写)在特定目录解开;
特别留意的是, -c, -t, -x不可同时出现在一串命令列中。
-z :使用gzip进行压缩或解压缩,文件名最好为*.tar.gz
-j :使用bzip2进行压缩或解压缩,文件名最好为*.tar.bz2
-J :使用xz进行压缩或解压缩,文件名最好为 *.tar.xz
特别留意, -z, -j, -J 不可以同时出现在一串命令列中
-v :在压缩/解压缩的过程中,将正在处理的文件名显示出来!
-f filename :-f后面被处理的文件名!建议-f单独写一个选项!(比较不会忘记)
-C 目录 :该选项用于解压缩,解压缩到指定的目录内。
-p(小写) :保留备份数据的原本权限与属性,常用于备份(-c)重要的配置文件
-P(大写) :保留绝对路径,亦即允许备份数据中含有根目录存在之意;
--exclude=FILE:在压缩的过程中,不要将 FILE 打包!
其实最简单的使用 tar 就只要记忆下面的方式即可: tar常用的选项组合如下: 压缩:
              [peter@study ~]$ tar -jcv -f 压缩后的文件filename.tar.bz2 被压缩的文件或目录名称
            
解压缩:
              [peter@study ~]$ tar -jxv -f 解压文件filename.tar.bz2 -C 解压缩到该目录
            
查询:
              [peter@study ~]$ tar -jtv -f filename.tar.bz2
            
那个 filename.tar.bz2 是我们自己取的文件名,tar 并不会主动的产生建立的文件名喔!我们要自定义啦!
所以扩展名就显的很重要了!如果不加 [-z|-j|-J] 的话,文件名最好取为 *.tar 即可。
tar命令需要用户给出打包压缩后的文件名,如果只是打包而不压缩,只需使用-c选项即可,打包后的文件扩展名最好是*.tar;
如果需要打包完后再压缩,就在-c选项的基础上加上-z或者-j或者-J,分别使用gzip, bzip2和xz进行压缩。
-j选项使用bzip2压缩,文件名最好就取为*.tar.bz2;
-z选项使用gzip压缩,文件名最好取为*.tar.gz;
-J选项使用xz压缩,文件名最好取为*.tar.xz;
-f filename是紧接在一起的, 所以可以写成-jcvf filename, 但由于选项的顺序理论上是可以变换的,所以很多用户会误认为-jvfc filename也可以。事实上这样会导致tar产生的文件名变成c! 所以建议在使用tar的时候最好将-f filename与其他选项独立出来。
经常需要备份系统的/etc目录,可以使用tar进行备份。

2.使用gzip算法打包压缩

回到顶部
使用gzip算法打包压缩/etc目录,使用进行压缩,保留文件的原权限和属性,同时显示压缩过程信息:
            [root@initroot ~]# tar -zpcv -f /root/etc.tar.gz /etc
            tar: Removing leading `/' from member names
            /etc/
            /etc/machine-id
            /etc/udisks2/
            /etc/udisks2/udisks2.conf
            ...省略...
            
-v选项,可以将正在压缩的文件名显示在屏幕上。
-p选项保留原本文件的权限与属性。类似cp命令的-p选项,在备份重要的系统数据时,最好将原本文件的权限做完整的备份。

3.使用bzip2算法打包压缩

回到顶部
使用bzip2算法打包压缩/etc目录:
            [root@initroot ~]#tar -jpcv -f /root/etc.tar.bz2 /etc
            tar: Removing leading `/' from member names
            /etc/
            /etc/machine-id
            /etc/udisks2/
            ...省略...
            

4.使用xz算法打包压缩

回到顶部
使用xz算法打包压缩/etc目录:
            [root@initroot ~]#tar -Jpcv -f /root/etc.tar.xz /etc          
            tar: Removing leading `/' from member names
            /etc/
            /etc/machine-id
            /etc/udisks2/
            ...省略...
            
查看打包压缩后的文件大小:
            [root@initroot ~]# ls -lh /root/etc.tar.*
            -rw-r--r-- 1 root root 1.7M Mar  2 10:43 /root/etc.tar.bz2
            -rw-r--r-- 1 root root 1.9M Mar  2 10:38 /root/etc.tar.gz
            -rw-r--r-- 1 root root 1.4M Mar  2 10:45 /root/etc.tar.xz
            
/etc目录所占用的磁盘空间:
            [root@initroot ~]# du -sm /etc
            15	/etc/
            
/etc目录约占28MB磁盘空间!
可以明显看到使用不同压缩算法,压缩后的文件大小对比。最好的是xz,但是在使用不同压缩算法时候,可以明显感觉到压缩率越高,占用的时间越多。
可以在上面打包压缩命令的前面加上time命令,测试打包压缩所用的时间。只需看real就可以了,以为xz压缩为例:
              [root@initroot ~]#time tar -Jpcv -f /root/etc.tar.xz /etc          
              tar: Removing leading `/' from member names
              /etc/
              /etc/machine-id
              /etc/udisks2/
              ...省略...
              /etc/mtab

              real	0m3.382s
              user	0m2.792s
              sys	0m0.155s
            
压缩比越好花费时间越多!。
使用tar打包压缩文件的时候会有警告信息tar: Removing leading `/' from member names
意思是在压缩的时候会将文件路径名最前面的/去掉,相当于只保留了文件的相对路径名。 去掉根目录是为了解压缩时候的数据安全, 例如在/tmp目录下解压缩,解压缩的文件名就会变成/tmp/etc/xxx。 如果没有去掉根目录,解压缩后的文件名会是绝对路径,就会覆盖掉/etc目录下的文件,这是非常危险的!
如果确定需要保留绝对路径,可以使用-P(大写)选项,将文件名中的根目录也备份下来:
            [root@initroot ~]# tar -jpPcv -f /root/etc.and.root.tar.bz2 /etc
            
加上-P选项,文件名内的根目录就会存在!为了解压缩时的数据安全建议不要加上-P选项来备份! 如果需要覆盖掉/etc目录下的文件,只需要在该目录下解压缩即可,或者指定解压缩的目录。

5.查看压缩文件

回到顶部
可以使用-t选项查看打包压缩后的文件,-v选项可以列出详细的文件权限和属性,像ls一样列出压缩文件中的文件:
            [root@initroot ~]# tar -jtv -f /root/etc.tar.bz2
            drwxr-xr-x root/root         0 2020-01-19 18:11 etc/
            -r--r--r-- root/root        33 2019-07-29 18:28 etc/machine-id
            ...省略...
            
可以看到文件名前面没有根目录/,显示的是相对路径名。

6.tar命令解压

回到顶部
将打包压缩后的文件解压缩:
            [root@initroot ~]# tar -jxv -f /root/etc.tar.bz2
            
因为我们是在家目录下进行的解压缩操作,所以会将文件解压缩到家目录下。 如果想要解压到其他目录,只需要切换到相应目录,然后进行解压缩即可。也可以使用-C选项指定解压缩的目录:
            [root@initroot ~]# tar -jxv -f /root/etc.tar.bz2 -C /tmp
            [root@initroot ~]# ls -l /tmp
            ...省略...
            drwxr-xr-x. 131 root root 8192 Jun 26 22:14 etc
            ...省略...
            
注意在解压的时候,用什么算法压缩,就要用相应的算法解压。
例如上面的etc.tar.bz2文件在压缩的时候使用-j为bzip2方式压缩,那么解压的时候-x就需要配合-j来使用bzip2方式进行解压。
删除测试目录:
            [root@initroot ~]# rm -rf /root/etc /tmp/etc
            
rm -rf是很危险的命令!请务必要确认后面接的文件名。要删除的是/root/etc与/tmp/etc, 不要将/etc/删除掉了!
上面是将整个压缩文件解压缩,也可以解压压缩文件内指定的文件:
              [root@initroot ~]# tar -jxv -f 压缩文件.tar.bz2 待解压文件名
            
可以先利用-jtv选项配合grep找出想要解压的文件,然后再对该文件进行解压。
例如只想要解压shadow文件,先看看压缩文件中有没有shadow文件:
            [root@initroot ~]# tar -jtv -f /root/etc.tar.bz2 | grep 'shadow'
            ---------- root/root 721 2015-06-17 00:20 etc/gshadow
            ---------- root/root 1183 2015-06-17 00:20 etc/shadow-
            ---------- root/root 1210 2015-06-17 00:20 etc/shadow     #有!
            ---------- root/root 707 2015-06-17 00:20 etc/gshadow-
            
然后再解压shadow文件:
            [root@initroot ~]# tar -jxv -f /root/etc.tar.bz2 etc/shadow
            etc/shadow
            
注意不要写成/etc/shadow!因为在etc.tar.bz2内并没有/!

7.tar命令--exclude选项

回到顶部
打包某目录,但不含该目录下的某些文件之作法
可以使用--exclude选项排除不需要打包的文件或目录。
假设想要打包/etc/和/root目录,但却不想要打包/root/etc*开头的文件,新打包文件为/root/system.tar.bz2:
            [root@initroot ~]# tar -jcv -f /root/system.tar.bz2 --exclude=/root/etc* --exclude=/root/system.tar.bz2 /etc /root
            
因为打包压缩后的文件system.tar.bz2存放在/root目录下,所以该文件也不需要打包,用--exclude排除掉。 上面的命令比较长,有可能一行放不下,可以使用换行符(\)+[enter]将命令接到下一行。
通过这个 --exclude="file" 的动作,我们可以将几个特殊的文件或目录移除在打包之列!

8.备份比某个时刻还要新的文件

回到顶部
某些情况下需要备份新的文件,并不想备份旧文件!
可以使用--newer或者--newer-mtime选项,当使用--newer时,表示后续的日期包含mtime与ctime,而--newer-mtime则仅包含mtime! 。
用find命令找出比/etc/passwd还要新的文件:
            [root@initroot ~]# find /etc -newer /etc/passwd
            ....省略...
            
此时会显示出比/etc/passwd文件的mtime还要新的文件名
            [root@initroot ~]# ll /etc/passwd
            -rw-r--r--. 1 root root 2020 Jun 17 00:20 /etc/passwd
            
使用tar来进行打包吧!日期为上面看到的 2020/06/17
            [root@initroot ~]# tar -jcv -f /root/etc.newer.then.passwd.tar.bz2 --newer-mtime="2015/06/17" /etc/*
            tar: Option --newer-mtime: Treating date `2020/06/17' as 2020-06-17 00:00:00
            tar: Removing leading `/' from member names
            /etc/abrt/
            ...省略...
            /etc/alsa/
            /etc/yum.repos.d/
            ...省略...
            tar: /etc/yum.repos.d/CentOS-fasttrack.repo: file is unchanged; not dumped
            
最后一行显示的是没有被备份的,即not dumped!
显示出文件:
            [root@initroot ~]# tar -jtv -f /root/etc.newer.then.passwd.tar.bz2 | grep -v '/$'
            
上面的命令可以调出tar.bz2内的非/结尾的文件名!就是我们需要的!
这个命令可以进行差异文件的记录与备份。
可以想象,如果在一个月前才进行过一次完整的数据备份, 这个月可以仅备份上个月进行备份的那个时间点之后的更新的文件即可!
只要备份新数据即可。可以降低备份的容量!

9.备份到特殊设备

回到顶部
tar命令除了可以将文件打包成为tarball或者tarfile外,还可以将文件打包到某些特殊设备中,例如磁带机(tape)。 由于磁带机是一次性读写设备,不能使用类似cp命令来复制! 如果想要将/home, /root, /etc备份到磁带机(/dev/st0):
              [root@initroot ~]# tar -cv -f /dev/st0 /home /root /etc
            

10.tar配合管道的使用

回到顶部
特殊应用:利用管线命令与数据流
在 tar 的使用中,有一种方式最特殊,那就是通过标准输入输出的数据流重导向(standard input/standard output), 以及管道命令(pipe)的方式,将待处理的文件一边打包一边解压缩到目标目录去。
将/etc目录一边打包一边在/tmp解开:
            [root@initroot ~]# cd /tmp
            [root@initroot tmp]# tar -cvf - /etc | tar -xvf -
            
上面的命令有点类似cp -r /etc /tmp!
要注意的是输出文件变成-,输入文件也变成-,分别表示standard output和standard input。|为管线符号!
可以将-简单的想成是在内存中的一个设备(缓冲区)。
我们想要将/etc下面的资料直接copy到/tmp目录下,但是又觉得使用 cp -r 有点麻烦,那么就直接以这个打包的方式来打包,命令里面的-就是表示那个被打包的文件啦! 由于我们不想要让中间文件存在,所以就以这一个方式来进行复制的行为!

11.系统备份示例

回到顶部
系统上有非常多的重要目录需要进行备份,不建议你将备份数据放置到/root目录下!
经常需要备份的目录有如下几个:
/etc/ (配置文件)
/home/ (用户的家目录)
/var/spool/mail/ (系统中,所有账号的邮件信箱)
/var/spool/cron/ (所有账号的工作排成配置文件)
/root (系统管理员的家目录)
假设将备份的数据放置到/backups目录下,该目录仅有root有权限!
此外,希望每次备份的文件名都不相同,例如使用:backup-system-20200701.tar.bz2之类的文件名。
1. 先处理要放置备份数据的目录与权限:
            [root@initroot ~]# mkdir /backups
            [root@initroot ~]# chmod 700 /backups
            [root@initroot ~]# ll -d /backups
            drwx------. 2 root root 6 Jul 1 17:25 /backups
            
2. 假设今天是2020/07/01,建立备份的方式如下:
            [root@initroot ~]# tar -jcv -f /backups/backup-system-20150701.tar.bz2 \
            > --exclude=/root/*.bz2 --exclude=/root/*.gz --exclude=/home/loop* \
            > /etc /home /var/spool/mail /var/spool/cron /root
            ...省略...
            
[root@initroot ~]# ll -h /backups/ -rw-r--r--. 1 root root 21M Jul 1 17:26 backup-system-20150701.tar.bz2

12.SELinux对解压缩的影响

回到顶部
SELinux是比较特别的细部权限设定机制,SELinux 的权限问题可能会让你的系统无法存取某些配置文件内容,导致影响到系统的正常使用权。
如果系统必须要以备份的数据来还原到原本的系统中,那么得要特别注意复原后的系统的SELinux问题! 尤其是系统文件,例如/etc目录下的文件。 通过tar去备份了/etc,然后尝试在另一部系统上面复原。 复原完毕之后,无法正常的登入系统! 使用单人维护模式去操作系统时看起来一切正常,但就是无法顺利登入。
其实这个问题倒是很常见!大部分原因就是因为/etc/shadow密码文件的SELinux类型在还原时被更改了!导致系统的登入程序无法顺利的存取它,才造成无法登入。
简单的处理方式有这几个:
通过各种可行的救援方式登入系统,然后修改/etc/selinux/config文件,将SELinux改成permissive模式,重新启动后系统就正常了;
在第一次复原系统后,不要立即重新启动!先使用restorecon -Rv /etc自动修复一下SELinux类型即可。
通过各种可行的方式登入系统,建立/.autorelabel文件,重新启动后系统会自动修复SELinux类型,并且又会再次重新启动,之后就正常了!

initroot编辑整理,转载请注明www.initroot.com

100次点赞 100次阅读