鸟哥的Linux私房菜读书笔记--压缩解压缩

1、压缩及解压缩(先压缩再读取后解压)

     <1>命令:$  gzip  -d  文件

          选项与参数:
                  -c :将压缩的数据输出到屏幕上,可透过数据流重导向来处理;
                  -d :解压缩的参数;  ##将原本的的.gz删除,回到原本的文件。
                  -t :可以用来检验一个压缩文件的一致性~看看文件有无错误;
                  -v :可以显示出原文件/压缩文件案的压缩比等信息;
                  -# :# 为数字的意思,代表压缩等级,-1 最快,但是压缩比最差、-9 最慢,但是压缩比最好!预设是 -6

           命令:$ zcat  文件名.gz

           命令:$ gzip -d  文件名

     <2>命令:$ bzip2 [-cdkxv#]   文件名

           选项与参数:
                 -c :将压缩的过程产生的数据输出到屏幕上!
                 -d :解压缩的参数
                 -k :保留源文件,而不会删除原始的文件喔!
                 -z :压缩的参数 (默认值,可以不加)
                 -v :可以显示出原文件/压缩文件案的压缩比等信息;
                 -# :与 gzip 同样的,都是在计算压缩比的参数, -9 最佳, -1 最快!

           命令:$ bzcat  文件名.bz2

           命令:$ bzip2  -d   文件名.bz2

     <3>命令:$  xz  [-dtlkc#]  文件名
         
           选项与参数:
                 -d :就是解压缩啊!
                 -t :测试压缩文件的完整性,看有没有错误
                  -l :列出压缩文件的相关信息
                 -k :保留原本的文件不删除~
                 -c :同样的,就是将数据由屏幕上输出的意思!
                 -# :同样的,也有较佳的压缩比的意思!

          命令:$  xcat  文件名.xz

          命令:$  xz   -d  文件名.xz

2、从压缩文件当中寻找数据;

    命令:$ zgrep         ##查找压缩文件中的关键字。

3、解压 :$ : tar -zxvf  解压缩的压缩包   指定位置       ##解压缩到指定位置

     命令:$ unzip  解压的文件    ##对zip文件的解压

    注意:gzip进行压缩时,在预设状态下原来的文件会被压缩成为.gz的档名,源文件就不再存在了。

4、打包
    命令:$  tar [-z|-j|-J] [cv] [-f 待建立的新檔名] filename... <==打包与压缩
    命令:$  tar [-z|-j|-J] [tv] [-f 既有的 tar 檔名]                     <==察看檔名
    命令:$  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 -jcv -f filename.tar.bz2 要被压缩的文件或目录名称
      · 查 询:tar -jtv -f filename.tar.bz2
      · 解压缩:tar -jxv -f filename.tar.bz2 -C 欲解压缩的目录

       由于『 -f filename 』是紧接在一起的,过去很多文章常会写成『-jcvf filename』,这样是对的,但由于选项的顺序理论上是可以变换的,所以很多读者会误认为『-jvfc filename』也可以~事实上这样会导致产生的档名变成 c ! 因为 -fc 嘛!所以啰,建议您在学习 tar 时,将『 -f filename 』与其他选项独立出来,会比较不容易发生问题。

    命令 :$ : tar -cvf  打包后的文件名  需要打包的文件    ##c:创建  v:过程  f:文件。

    命令:$ : tar -cvf 打包后的文件名  需要打包的文件  -c  新的目录    ##将文件打包至指定目录中。

5、解包

命令:$  tar -xvf 需要解包的文件

命令:$  tar -jvt  -f  打包文件   |  grep  ‘文件名’     

命令:$  tar  -jxv  -f  打包文件.tar.bz2  待解开档名

例:$  tar  -jxv  -f  /root/etc.tar.bz2  etc/shadow     ##本例中不能写成/etc/shadow!因为记录在etc.tar.bz2内并没有/之故

                                                                               ##打开打包文件中的某一个文件     

6、一次性完成打包&压缩操作

 命令 :$ : tar -zcvf  压缩后的文件名  需要打包的文件   ##压缩后的文件名一般为:文件名.tar.gz

7、备份

       使用tar加入-z,-j,-J等参数备份/etc

       命令:$   time  tar  -zpcv  -f  /root.etc.tar.gz   /etc

               选项与参数:

                       -v:将正在作用的文件名显示在屏幕上

                       -p:保留原本文件的权限与属性


以下为复制粘贴,可能在后续中使用到

§ 使用 tar 加入 -z, -j 或 -J 的参数备份 /etc/ 目录
有事没事备份一下 /etc 这个目录是件好事!备份 /etc 最简单的方法就是使用 tar 啰!让我们来玩玩
先:
[dmtsai@study ~]$ su - # 因为备份 /etc 需要 root 的权限,否则会出现一堆错误
[root@study ~]# time tar -zpcv -f /root/etc.tar.gz /etc
tar: Removing leading `/' from member names <==注意这个警告讯息
/etc/
....(中间省略)....
/etc/hostname
/etc/aliases.db
real 0m0.799s # 多了 time 会显示程序运作的时间!看 real 就好了!花去了 0.799s
user 0m0.767s
sys 0m0.046s
# 由于加上 -v 这个选项,因此正在作用中的文件名就会显示在屏幕上。
# 如果你可以翻到第一页,会发现出现上面的错误讯息!底下会讲解。
# 至于 -p 的选项,重点在于『保留原本文件的权限与属性』之意。
[root@study ~]# time tar -jpcv -f /root/etc.tar.bz2 /etc
....(前面省略)....
real 0m1.913s
user 0m1.881s
sys 0m0.038s
[root@study ~]# time tar -Jpcv -f /root/etc.tar.xz /etc
....(前面省略)....
real 0m9.023s
user 0m8.984s
sys 0m0.086s
# 显示的讯息会跟上面一模一样啰!不过时间会花比较多!使用了 -J 时,会花更多时间
[root@study ~]# ll /root/etc*
-rw-r--r--. 1 root root 6721809 Jul 1 00:16 /root/etc.tar.bz2
-rw-r--r--. 1 root root 7758826 Jul 1 00:14 /root/etc.tar.gz
-rw-r--r--. 1 root root 5511500 Jul 1 00:16 /root/etc.tar.xz
[root@study ~]# du -sm /etc
28 /etc # 实际目录约占有 28MB 的意思!
压缩比越好当然要花费的运算时间越多!我们从上面可以看到,虽然使用 gzip 的速度相当快,总时
间花费不到 1 秒钟,但是压缩率最糟糕! 如果使用 xz 的话,虽然压缩比最佳!不过竟然花了 9 秒
钟的时间耶!这还仅是备份 28MBytes 的 /etc 而已,如果备份的数据是很大容量的, 那你真的要
考虑时间成本才行!
至于加上『 -p 』这个选项的原因是为了保存原本文件的权限与属性!我们曾在第六章的 cp 指令介
绍时谈到权限与文件类型(例如连结档)对复制的不同影响。 同样的,在备份重要的系统数据时,这
些原本文件的权限需要做完整的备份比较好。此时 -p 这个选项就派的上用场了。 接下来让我们看
看打包文件内有什么数据存在?
§ 查阅 tar 文件的数据内容 (可察看檔名),与备份文件名有否根目录的意义
要察看由 tar 所建立的打包文件内部的档名非常的简单!可以这样做:
[root@study ~]# tar -jtv -f /root/etc.tar.bz2
....(前面省略)....
-rw-r--r-- root/root 131 2015-05-25 17:48 etc/locale.conf
-rw-r--r-- root/root 19 2015-05-04 17:56 etc/hostname
-rw-r--r-- root/root 12288 2015-05-04 17:59 etc/aliases.db
如果加上 -v 这个选项时,详细的文件权限/属性都会被列出来!如果只是想要知道檔名而已, 那么
就将 -v 拿掉即可。从上面的数据我们可以发现一件很有趣的事情,那就是每个文件名都没了根目录
了!这也是上一个练习中出现的那个警告讯息『tar: Removing leading `/' from member names(移除了档
名开头的 `/' )』所告知的情况!
那为什么要拿掉根目录呢?主要是为了安全!我们使用 tar 备份的数据可能会需要解压缩回来使
用,在 tar 所记录的文件名 (就是我们刚刚使用 tar -jtvf 所察看到的檔名) 那就是解压缩后的实际档
名。如果拿掉了根目录,假设你将备份数据在 /tmp 解开,那么解压缩的档名就会变成『/tmp/etc/xxx』。
但『如果没有拿掉根目录,解压缩后的档名就会是绝对路径, 亦即解压缩后的数据一定会被放置
到 /etc/xxx 去!』如此一来,你的原本的 /etc/ 底下的数据, 就会被备份数据所覆盖过去了!
Tips 你会说:『既然是备份数据,那么还原回来也没有什么问题吧?』想象一个状况,你备
份的资料是两年前的旧版 CentOS 6.x, 你只是想要了解一下过去的备份内容究竟有哪些数据而已,结果一解开该
文件,却发现你目前新版的 CentOS 7.x 底下的 /etc 被旧版的备份数据覆盖了!此时你该如何是好?大概除了哭哭
你也不能做啥事吧?所以啰,当然是拿掉根目录比较安全一些的。
如果你确定你就是需要备份根目录到 tar 的文件中,那可以使用 -P (大写) 这个选项,请看底下的例子分析
范例:将文件名中的(根)目录也备份下来,并察看一下备份档的内容档名
[root@study ~]# tar -jpPcv -f /root/etc.and.root.tar.bz2 /etc
[root@study ~]# tar -jtf /root/etc.and.root.tar.bz2
/etc/locale.conf
/etc/hostname
/etc/aliases.db
# 这次查阅文件名不含 -v 选项,所以仅有文件名而已!没有详细属性/权限等参数。
有发现不同点了吧?如果加上 -P 选项,那么文件名内的根目录就会存在喔!不过,鸟哥个人建议,
还是不要加上 -P 这个选项来备份! 毕竟很多时候,我们备份是为了要未来追踪问题用的,倒不一
定需要还原回原本的系统中! 所以拿掉根目录后,备份数据的应用会比较有弹性!也比较安全呢!
§ 将备份的数据解压缩,并考虑特定目录的解压缩动作 (-C 选项的应用)
那如果想要解打包呢?很简单的动作就是直接进行解打包嘛!
[root@study ~]# tar -jxv -f /root/etc.tar.bz2
[root@study ~]# ll
....(前面省略)....
drwxr-xr-x. 131 root root 8192 Jun 26 22:14 etc
....(后面省略)....
此时该打包文件会在『本目录下进行解压缩』的动作! 所以,你等一下就会在家目录底下发现一个
名为 etc 的目录啰!所以啰,如果你想要将该文件在 /tmp 底下解开, 可以 cd /tmp 后,再下达上
述的指令即可。不过,这样好像很麻烦呢~有没有更简单的方法可以『指定欲解开的目录』呢? 有
的,可以使用 -C 这个选项喔!举例来说:
[root@study ~]# tar -jxv -f /root/etc.tar.bz2 -C /tmp
[root@study ~]# ll /tmp
....(前面省略)....
drwxr-xr-x. 131 root root 8192 Jun 26 22:14 etc
....(后面省略)....
这样一来,你就能够将该文件在不同的目录解开啰!鸟哥个人是认为,这个 -C 的选项务必要记忆一
下的! 好了,处理完毕后,请记得将这两个目录删除一下呢!
[root@study ~]# rm -rf /root/etc /tmp/etc
再次强调,这个『 rm -rf 』是很危险的指令!下达时请务必要确认一下后面接的档名。我们要删除
的是 /root/etc 与 /tmp/etc, 您可不要将 /etc/ 删除掉了!系统会死掉的~ ^_^

§ 仅解开单一文件的方法

刚刚上头我们解压缩都是将整个打包文件的内容全部解开!想象一个情况,如果我只想要解开打包文
件内的其中一个文件而已, 那该如何做呢?很简单的,你只要使用 -jtv 找到你要的档名,然后将该
档名解开即可。 我们用底下的例子来说明一下:
# 1. 先找到我们要的档名,假设解开 shadow 文件好了:
[root@study ~]# 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-
# 先搜寻重要的档名!其中那个 grep 是『撷取』关键词的功能!我们会在第三篇说明!
# 这里您先有个概念即可!那个管线 | 配合 grep 可以撷取关键词的意思!
# 2. 将该文件解开!语法与实际作法如下:
[root@study ~]# tar -jxv -f 打包檔.tar.bz2 待解开档名
[root@study ~]# tar -jxv -f /root/etc.tar.bz2 etc/shadow
etc/shadow
[root@study ~]# ll etc
total 4
----------. 1 root root 1210 Jun 17 00:20 shadow
# 很有趣!此时只会解开一个文件而已!不过,重点是那个档名!你要找到正确的档名。
# 在本例中,你不能写成 /etc/shadow !因为记录在 etc.tar.bz2 内的并没有 / 之故!
Tips 在这个练习之前,你可能要先将前面练习所产生的 /root/etc 删除才行!不然
/root/etc/shadow 会重复存在,而其他的前面实验的文件也会存在, 那就看不出什么鬼~
§ 打包某目录,但不含该目录下的某些文件之作法
假设我们想要打包 /etc/ /root 这几个重要的目录,但却不想要打包 /root/etc* 开头的文件,因为该文
件都是刚刚我们才建立的备份档嘛! 而且假设这个新的打包文件要放置成为 /root/system.tar.bz2 ,
当然这个文件自己不要打包自己 (因为这个文件放置在 /root 底下啊!),此时我们可以透过 --exclude 
的帮忙! 那个 exclude 就是不包含的意思!所以你可以这样做:
[root@study ~]# tar -jcv -f /root/system.tar.bz2 --exclude=/root/etc* \
> --exclude=/root/system.tar.bz2 /etc /root
上面的指令是一整列的~其实你可以打成:『tar -jcv -f /root/system.tar.bz2 --exclude=/root/etc* 
--exclude=/root/system.tar.bz2 /etc /root』,如果想要两行输入时,最后面加上反斜杠 (\) 并立刻按下
[enter] , 就能够到第二行继续输入了。这个指令下达的方式我们会在第三章再仔细说明。 透过这
个 --exclude="file" 的动作,我们可以将几个特殊的文件或目录移除在打包之列,让打包的动作变的
更简便喔!^_^

§ 仅备份比某个时刻还要新的文件


某些情况下你会想要备份新的文件而已,并不想要备份旧文件!此时 --newer-mtime 这个选项就粉重
要啦! 其实有两个选项啦,一个是『 --newer 』另一个就是『 --newer-mtime 』,这两个选项有何
不同呢? 我们在第六章的 touch 介绍中谈到过三种不同的时间参数, 当使用 --newer 时,表示后续
的日期包含『 mtime 与 ctime 』,而 --newer-mtime 则仅是 mtime 而已! 这样知道了吧! ^_^ 。
那就让我们来尝试处理一下啰!
# 1. 先由 find 找出比 /etc/passwd 还要新的文件
[root@study ~]# find /etc -newer /etc/passwd
....(过程省略)....
# 此时会显示出比 /etc/passwd 这个文件的 mtime 还要新的档名,
# 这个结果在每部主机都不相同!您先自行查阅自己的主机即可,不会跟鸟哥一样!
[root@study ~]# ll /etc/passwd
-rw-r--r--. 1 root root 2092 Jun 17 00:20 /etc/passwd
# 2. 好了,那么使用 tar 来进行打包吧!日期为上面看到的 2015/06/17
[root@study ~]# tar -jcv -f /root/etc.newer.then.passwd.tar.bz2 \
> --newer-mtime="2015/06/17" /etc/*
tar: Option --newer-mtime: Treating date `2015/06/17' as 2015-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 的意思!
# 3. 显示出文件即可
[root@study ~]# tar -jtv -f /root/etc.newer.then.passwd.tar.bz2 | grep -v '/$' 
# 透过这个指令可以呼叫出 tar.bz2 内的结尾非 / 的檔名!就是我们要的啦!
现在你知道这个指令的好用了吧!甚至可以进行差异文件的记录与备份呢~ 这样子的备份就会显的
更容易啰!你可以这样想象,如果我在一个月前才进行过一次完整的数据备份, 那么这个月想要备
份时,当然可以仅备份上个月进行备份的那个时间点之后的更新的文件即可! 为什么呢?因为原本
的文件已经有备份了嘛!干嘛还要进行一次?只要备份新数据即可。这样可以降低备份的容量啊

§ 基本名称: tarfile, tarball ?

另外值得一提的是,tar 打包出来的文件有没有进行压缩所得到文件称呼不同喔!如果仅是打包而已,
就是『 tar -cv -f file.tar 』而已,这个文件我们称呼为 tarfile 。如果还有进行压缩的支持,例如『 tar 
-jcv -f file.tar.bz2 』时,我们就称呼为 tarball (tar 球?)!这只是一个基本的称谓而已,不过很多书籍
与网络都会使用到这个 tarball 的名称!所以得要跟您介绍介绍。
此外,tar 除了可以将资料打包成为文件之外,还能够将文件打包到某些特别的装置去,举例来说,磁
带机 (tape) 就是一个常见的例子。磁带机由于是一次性读取/写入的装置,因此我们不能够使用类似
cp 等指令来复制的! 那如果想要将 /home, /root, /etc 备份到磁带机 (/dev/st0) 时,就可以使用:『tar 
-cv -f /dev/st0 /home /root /etc』,很简单容易吧! 磁带机用在备份 (尤其是企业应用) 是很常见的工
作喔!

§ 特殊应用:利用管线命令与数据流


在 tar 的使用中,有一种方式最特殊,那就是透过标准输入输出的数据流重导向(standard 
input/standard output), 以及管线命令 (pipe) 的方式,将待处理的文件一边打包一边解压缩到目标目
录去。 关于数据流重导向与管线命令更详细的数据我们会在第十章 bash 再跟大家介绍, 底下先来
看一个例子吧!
# 1. 将 /etc 整个目录一边打包一边在 /tmp 解开
[root@study ~]# cd /tmp
[root@study tmp]# tar -cvf - /etc | tar -xvf -
# 这个动作有点像是 cp -r /etc /tmp 啦~依旧是有其有用途的!
# 要注意的地方在于输出档变成 - 而输入档也变成 - ,又有一个 | 存在~
# 这分别代表 standard output, standard input 与管线命令啦!
# 简单的想法中,你可以将 - 想成是在内存中的一个装置(缓冲区)。
# 更详细的数据流与管线命令,请翻到 bash 章节啰!
在上面的例子中,我们想要『将 /etc 底下的资料直接 copy 到目前所在的路径,也就是 /tmp 底下』,
但是又觉得使用 cp -r 有点麻烦,那么就直接以这个打包的方式来打包,其中,指令里面的 - 就是
表示那个被打包的文件啦! 由于我们不想要让中间文件存在,所以就以这一个方式来进行复制的行
为啦!
§ 例题:系统备份范例
系统上有非常多的重要目录需要进行备份,而且其实我们也不建议你将备份数据放置到 /root 目录下!
假设目前你已经知道重要的目录有底下这几个:
· /etc/ (配置文件)
· /home/ (用户的家目录)
· /var/spool/mail/ (系统中,所有账号的邮件信箱)
· /var/spool/cron/ (所有账号的工作排成配置文件)
· /root (系统管理员的家目录)
然后我们也知道,由于第七章曾经做过的练习的关系, /home/loop* 不需要备份,而且 /root 底下的
压缩文件也不需要备份,另外假设你要将备份的数据放置到 /backups ,并且该目录仅有 root 有权
限进入! 此外,每次备份的档名都希望不相同,例如使用:backup-system-20150701.tar.bz2 之类的
档名来处理。 那你该如何处理这个备份数据呢?(请先动手作看看,再来察看一下底下的参考解答!)
# 1. 先处理要放置备份数据的目录与权限:
[root@study ~]# mkdir /backups
[root@study ~]# chmod 700 /backups
[root@study ~]# ll -d /backups
drwx------. 2 root root 6 Jul 1 17:25 /backups
# 2. 假设今天是 2015/07/01 ,则建立备份的方式如下:
[root@study ~]# 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@study ~]# ll -h /backups/
-rw-r--r--. 1 root root 21M Jul 1 17:26 backup-system-20150701.tar.bz2

§ 解压缩后的 SELinux 课题


如果,鸟哥是说如果,如果因为某些缘故,所以你的系统必须要以备份的数据来回填到原本的系统中,
那么得要特别注意复原后的系统的 SELinux 问题! 尤其是在系统文件上面!例如 /etc 底下的文件
群。SELinux 是比较特别的细部权限设定,相关的介绍我们会在 16 章好好的介绍一下。 在这里,
你只要先知道,SELinux 的权限问题『可能会让你的系统无法存取某些配置文件内容,导致影响到系
统的正常使用权』。
这两天 (2015/07) 接到一个网友的 email,他说他使用鸟哥介绍的方法透过 tar 去备份了 /etc 的数
据,然后尝试在另一部系统上面复原回来。 复原倒是没问题,但是复原完毕之后,无论如何就是无
法正常的登入系统!明明使用单人维护模式去操作系统时,看起来一切正常~但就是无法顺利登入。
其实这个问题倒是很常见!大部分原因就是因为 /etc/shadow 这个密码文件的 SELinux 类型在还原
时被更改了!导致系统的登入程序无法顺利的存取它, 才造成无法登入的窘境。
那如何处理呢?简单的处理方式有这几个:
· 透过各种可行的救援方式登入系统,然后修改 /etc/selinux/config 文件,将 SELinux 改成 permissive 模式,
重新启动后系统就正常了;
· 在第一次复原系统后,不要立即重新启动!先使用 restorecon -Rv /etc 自动修复一下 SELinux 的类型即可。
· 透过各种可行的方式登入系统,建立 /.autorelabel 文件,重新启动后系统会自动修复 SELinux 的类型,并
且又会再次重新启动,之后就正常了!
鸟哥个人是比较偏好第 2 个方法,不过如果忘记了该步骤就重新启动呢?那鸟哥比较偏向使用第 3 
个方案来处理,这样就能够解决复原后的 SELinux 问题啰! 至于更详细的 SELinux ,我们得要讲
完程序 (process) 之后,你才会有比较清楚的认知,因此还请慢慢学习,到第 16 章你就知道问题点

猜你喜欢

转载自blog.csdn.net/qq_41825534/article/details/82822049