来自《鸟哥的 Linux 私房菜》,重复只是加深自己的印象。
一、Linux 系统常见的压缩指令
列出几个常见的压缩文件扩展名:
*.Z compress 程序压缩的文件;
*.zip zip 程序压缩的文件;
*.gz gzip 程序压缩的文件;
*.bz2 bzip2 程序压缩的文件;
*.xz xz 程序压缩的文件;
*.tar tar 程序打包的数据,并没有压缩过;
*.tar.gz tar 程序打包的文件,其中并且经过 gzip 的压缩
*.tar.bz2 tar 程序打包的文件,其中并且经过 bzip2 的压缩
*.tar.xz tar 程序打包的文件,其中并且经过 xz 的压缩
Linux上常见的压缩指令就是 gzip, bzip2 以及最新的 xz ,至于 compress 已经退流行了。
为了支持 windows 常见的 zip, Linux 也就有 zip 指令了!
gzip 是由 GNU 计划所开发出来的压缩指令,该指令已经取代了 compress 。
后来 GNU 又开发出 bzip2 及 xz 这几个压缩比更好的压缩指令!
不过,这些指令通常仅能针对一个文件来压缩与解压缩,如此一来, 每次压缩与解压缩都要一大堆文件,岂不烦人?此时,那个所谓的“打包软件, tar”就显的很重要!
tar 可以将很多文件“打包”成为一个文件!甚至是目录也可以这么玩。不过,单纯的 tar 功能仅是“打包”而已,亦即是将很多文件集结成为一个文件, 事实上,他并没有提供压缩的功能,后来,GNU 计划中,将整个 tar 与压缩的功能结合在一起,如此一来提供使用者更方便并且更强大的压缩与打包功能!
1.1、gzip, zcat/zmore/zless/zgrep
gzip 可以说是应用度最广的压缩指令了!目前 gzip 可以解开 compress, zip 与 gzip 等软件所压缩的文件。 至于 gzip 所创建的压缩文件为 *.gz 的文件名。
gzip [-cdtv#] 文件名
选项与参数:
-c :将压缩的数据输出到屏幕上,可通过数据流重导向来处理;
-d :解压缩的参数;
-t :可以用来检验一个压缩文件的一致性~看看文件有无错误;
-v :可以显示出原文件/压缩文件的压缩比等信息;
-# :# 为数字的意思,代表压缩等级,-1 最快,但是压缩比最差、-9 最慢,但是压缩比最好!默认是 -6
范例一:找出 /etc 下面 (不含子目录) 容量最大的文件,并将它复制到 /tmp ,然后以 gzip 压缩
[dmtsai@study ~]$ ls -ldSr /etc/* # 忘记选项意义?请自行 man!
.....(前面省略).....
-rw-r--r--. 1 root root 25213 Jun 10 2014 /etc/dnsmasq.conf
-rw-r--r--. 1 root root 69768 May 4 17:55 /etc/ld.so.cache
-rw-r--r--. 1 root root 670293 Jun 7 2013 /etc/services
[dmtsai@study ~]$ cd /tmp
[dmtsai@study tmp]$ cp /etc/services .
[dmtsai@study tmp]$ gzip -v services
services: 79.7% -- replaced with services.gz
[dmtsai@study tmp]$ ll /etc/services /tmp/services*
-rw-r--r--. 1 root root 670293 Jun 7 2013 /etc/services
-rw-r--r--. 1 dmtsai dmtsai 136088 Jun 30 18:40 /tmp/services.gz
使用 gzip 进行压缩时,在默认的状态下原本的文件会被压缩成为 .gz 的文件名,原始文件就不再存在了。
范例二:由于 services 是文本文件,请将范例一的压缩文件的内容读出来!
[dmtsai@study tmp]$ zcat services.gz
# 由于 services 这个原本的文件是是文本文件,因此我们可以尝试使用 zcat/zmore/zless 去读取!
# 此时屏幕上会显示 servcies.gz 解压缩之后的原始文件内容!
范例三:将范例一的文件解压缩
[dmtsai@study tmp]$ gzip -d services.gz
# 鸟哥不要使用 gunzip 这个指令,不好背!使用 gzip -d 来进行解压缩!
# 与 gzip 相反, gzip -d 会将原本的 .gz 删除,回复到原本的 services 文件。
范例四:将范例三解开的 services 用最佳的压缩比压缩,并保留原本的文件
[dmtsai@study tmp]$ gzip -9 -c services > services.gz
范例五:由范例四再次创建的 services.gz 中,找出 http 这个关键字在哪几行?
[dmtsai@study tmp]$ zgrep -n 'http' services.gz
14:# http://www.iana.org/assignments/port-numbers
89:http 80/tcp www www-http # WorldWideWeb HTTP
90:http 80/udp www www-http # HyperText Transfer Protocol
.....(下面省略).....
# -c 可以将原本要转成压缩文件的数据内容,将它变成文字类型从屏幕输出, 然后通过大于 (>) 这个符号,将原本应该由屏幕输出的数据,转成输出到文件而不是屏幕,所以就能够创建出压缩挡了。
cat/more/less 可以使用不同的方式来读取纯文本文件,那个 zcat/zmore/zless 则可以对应于 cat/more/less 的方式来读取纯文本文件被压缩后的压缩文件!
由于 gzip 这个压缩指令主要想要用来取代 compress 的,所以不但 compress 的压缩文件可以使用 gzip 来解开,同时 zcat这个指令可以同时读取 compress 与 gzip 的压缩文件。
1.2、bzip2, bzcat/bzmore/bzless/bzgrep
若说 gzip 是为了取代 compress 并提供更好的压缩比而成立的,那么 bzip2 则是为了取代 gzip 并提供更佳的压缩比而来的。
bzip2 的用法几乎与 gzip 相同。
bzip2 [-cdkzv#] 文件名
选项与参数:
-c :将压缩的过程产生的数据输出到屏幕上!
-d :解压缩的参数
-k :保留原始文件,而不会删除原始的文件!
-z :压缩的参数 (默认值,可以不加)
-v :可以显示出原文件/压缩文件的压缩比等信息;
-# :与 gzip 同样的,都是在计算压缩比的参数, -9 最佳, -1 最快!
范例一:将刚刚 gzip 范例留下来的 /tmp/services 以 bzip2 压缩
[dmtsai@study tmp]$ bzip2 -v services
services: 5.409:1, 1.479 bits/Byte, 81.51% saved, 670293 in, 123932 out.
[dmtsai@study tmp]$ ls -l services*
-rw-r--r--. 1 dmtsai dmtsai 123932 Jun 30 18:40 services.bz2
-rw-rw-r--. 1 dmtsai dmtsai 135489 Jun 30 18:46 services.gz
# 此时 services 会变成 services.bz2 之外,你也可以发现 bzip2 的压缩比要较 gzip 好喔!!
# 压缩率由 gzip 的 79% 提升到 bzip2 的 81% 哩!
范例二:将范例一的文件内容读出来!
[dmtsai@study tmp]$ bzcat services.bz2
范例三:将范例一的文件解压缩
[dmtsai@study tmp]$ bzip2 -d services.bz2
范例四:将范例三解开的 services 用最佳的压缩比压缩,并保留原本的文件
[dmtsai@study tmp]$ bzip2 -9 -c services > services.bz2
1.3、xz, xzcat/xzmore/xzless/xzgrep
虽然 bzip2 已经具有很棒的压缩比,不过显然某些自由软件开发者还不满足,因此后来还推出了 xz 这个压缩比更高的软件!这个软件的用法也跟 gzip/bzip2 几乎一模一样!
xz [-dtlkc#] 文件名
选项与参数:
-d :就是解压缩!
-t :测试压缩文件的完整性,看有没有错误
-l :列出压缩文件的相关信息
-k :保留原本的文件不删除~
-c :同样的,就是将数据由屏幕上输出的意思!
-# :同样的,也有较佳的压缩比的意思!
范例一:将刚刚由 bzip2 所遗留下来的 /tmp/services 通过 xz 来压缩!
[dmtsai@study tmp]$ xz -v services
services (1/1)
100 % 97.3 KiB / 654.6 KiB = 0.149
[dmtsai@study tmp]$ ls -l services*
-rw-rw-r--. 1 dmtsai dmtsai 123932 Jun 30 19:09 services.bz2
-rw-rw-r--. 1 dmtsai dmtsai 135489 Jun 30 18:46 services.gz
-rw-r--r--. 1 dmtsai dmtsai 99608 Jun 30 18:40 services.xz
# 各位观众!看到没有啊!!容量又进一步下降的更多耶!好棒的压缩比!
范例二:列出这个压缩文件的信息,然后读出这个压缩文件的内容
[dmtsai@study tmp]$ xz -l services.xz
Strms Blocks Compressed Uncompressed Ratio Check Filename
1 1 97.3 KiB 654.6 KiB 0.149 CRC64 services.xz
# 竟然可以列出这个文件的压缩前后的容量,真是太人性化了!这样观察就方便多了!
[dmtsai@study tmp]$ xzcat services.xz
范例三:将他解压缩吧!
[dmtsai@study tmp]$ xz -d services.xz
范例四:保留原文件的文件名,并且创建压缩文件!
[dmtsai@study tmp]$ xz -k services
gzip,bzip2,xz 压缩比依次增加,但消耗的时间也增加。如果时间是你的重要成本,那么 gzip 恐怕是比较适合的压缩软件。
二、打包指令: tar
将多个文件或目录包成一个大文件的指令功能,是一种“打包指令”。
tar 可以将多个目录或文件打包成一个大文件,同时还可以通过 gzip/bzip2/xz 的支持,将该文件同时进行压缩!
2.1、tar
tar 的选项与参数非常的多!可以自行 man tar 查询,这里只列几个常用参数。
[dmtsai@study ~]$ tar [-z|-j|-J] [cv] [-f 待创建的新文件名] filename... ## ==打包与压缩
[dmtsai@study ~]$ tar [-z|-j|-J] [tv] [-f 既有的 tar文件名] ## ==察看文件名
[dmtsai@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 -j<u>c</u>v -f filename.tar.bz2 要被压缩的文件或目录名称
- 查 询:tar -j<u>t</u>v -f filename.tar.bz2
- 解压缩:tar -j<u>x</u>v -f filename.tar.bz2 -C 欲解压缩的目录
tar 并不会主动的产生创建的文件名,需要自行指定。所以扩展名就显的很重要了!如果不加 [-z|-j|-J] 的话,文件名最好取为 .tar 即可。如果是 -j 选项,代表有 bzip2 的支持,因此文件名最好就取为 *.tar.bz2 ,至于如果是加上了 -z 的 gzip 的支持,那文件名最好取为 *.tar.gz。
2.1.1、使用 tar 加入 -z, -j 或 -J 的参数备份 /etc/ 目录
[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 的意思!
2.1.2、查阅 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/<u>etc/xxx</u>”。 但“如果没有拿掉根目录,解压缩后的文件名就会是绝对路径, 亦即解压缩后的数据一定会被放置到 <u>/etc/xxx</u> 去!”如此一来,原本的/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 选项,所以仅有文件名而已!没有详细属性/权限等参数。
2.1.3、将备份的数据解压缩,并考虑特定目录的解压缩动作 (-C 选项的应用)
tar -jxv -f /root/etc.tar.bz2 -C /tmp
2.1.4、仅解开单一文件的方法
# 1. 先找到我们要的档名,假设解开 shadow 文件好了:
[root@www ~]# tar -jtv -f /root/etc.tar.bz2 | grep 'shadow'
-r-------- root/root 1230 2008-09-29 02:21:20 etc/shadow-
-r-------- root/root 622 2008-09-29 02:21:20 etc/gshadow-
-r-------- root/root 636 2008-09-29 02:21:25 etc/gshadow
-r-------- root/root 1257 2008-09-29 02:21:25 etc/shadow <==这是我们要的!
# 先搜寻重要的档名!其中那个 grep 是『撷取』关键字的功能!
# 那个管线 | 配合 grep 可以撷取关键字的意思!
# 2. 将该文件解开!语法与实际作法如下:
[root@www ~]# tar -jxv -f 打包档.tar.bz2 待解开档名
[root@www ~]# tar -jxv -f /root/etc.tar.bz2 etc/shadow
etc/shadow
[root@www ~]# ll etc
total 8
-r-------- 1 root root 1257 Sep 29 02:21 shadow
# 很有趣!此时只会解开一个文件而已!不过,重点是那个档名!你要找到正确的档名。
# 在本例中,你不能写成 /etc/shadow !因为记录在 etc.tar.bz2 内的档名之故!
2.1.5、打包某目录,但不含该目录下的某些文件之作法
想要打包 /etc/ /root 这几个重要的目录,但却不想要打包 /root/etc* 开头的文件
[root@www ~]# tar -jcv -f /root/system.tar.bz2 --exclude=/root/etc* \
> --exclude=/root/system.tar.bz2 /etc /root
2.1.6、仅备份比某个时刻还要新的文件
某些情况下想要备份新的文件而已,并不想要备份旧文件!此时 --newer-mtime 这个选项就很粉重要! 其实有两个选项啦,一个是『 --newer 』另一个就是『 --newer-mtime 』,当使用 --newer 时,表示后续的日期包含『 mtime 与 ctime 』,而 --newer-mtime 则仅是 mtime 而已。
# 1. 先由 find 找出比 /etc/passwd 还要新的文件
[root@www ~]# find /etc -newer /etc/passwd
....(过程省略)....
# 此时会显示出比 /etc/passwd 这个文件的 mtime 还要新的档名,
# 这个结果在每部主机都不相同!您先自行查阅自己的主机即可,不会跟鸟哥一样!
[root@www ~]# ll /etc/passwd
-rw-r--r-- 1 root root 1945 Sep 29 02:21 /etc/passwd
# 2. 好了,那么使用 tar 来进行打包吧!日期为上面看到的 2008/09/29
[root@www ~]# tar -jcv -f /root/etc.newer.then.passwd.tar.bz2 \
> --newer-mtime="2008/09/29" /etc/*
....(中间省略)....
/etc/smartd.conf <==真的有备份的文件
....(中间省略)....
/etc/yum.repos.d/ <==目录都会被记录下来!
tar: /etc/yum.repos.d/CentOS-Base.repo: file is unchanged; not dumped
# 最后行显示的是『没有被备份的』,亦即 not dumped 的意思!
# 3. 显示出文件即可
[root@www ~]# tar -jtv -f /root/etc.newer.then.passwd.tar.bz2 | \
> grep -v '/$'
# 透过这个命令可以呼叫出 tar.bz2 内的结尾非 / 的档名!就是我们要的啦!