您的位置:首页 > 运维架构 > Linux

Linux学习笔记(九)

2012-07-15 10:57 225 查看
文件的压缩与打包
在Linux中,有很多压缩命令。利用这些压缩命令,可以方便地从网络上下载大型文件。此外,我们知道,Linux的扩展名是没有什么特殊意义的,不过,针对这些压缩命令所做出来的压缩文件,为了方便记忆,还是会有一些特殊的命名方式。

Linux常见的压缩命令

几个常见的压缩档案扩展名:

*.Z compress 程序压缩的档案;

*.gz gzip 程序压缩的档案;

*.bz2 bzip2 程序压缩的档案;

*.tar tar 程序打包的数据,并没有压缩过;

*.tar.gz tar 程序打包的档案,其中并且经过 gzip 的压缩

*.tar.bz2 tar 程序打包的档案,其中并且经过 bzip2 的压缩

Linux上常见的压缩指令就是 gzip 与 bzip2 ,至于 compress 已经不流行了。

gzip、zcat命令

gzip 可以说是应用度最广的压缩指令了!目前 gzip 可以解开 compress, zip 与 gzip 等软件所压缩的档案。 至于 gzip 所建立的压缩档为 *.gz 的档名喔!

[root@www ~]# gzip [-cdtv#] 档名

[root@www ~]# zcat 档名.gz

选项与参数:

-c :将压缩的数据输出到屏幕上,可透过数据流重导向来处理;

-d :解压缩的参数;

-t :可以用来检验一个压缩档的一致性~看看档案有无错误;

-v :可以显示出原档案/压缩档案的压缩比等信息;

-# :压缩等级,-1 最快,但是压缩比最差、-9 最慢,但是压缩比最好!预设是 -6

范例一:将 /etc/man.config 复制到 /tmp ,并且以 gzip 压缩

[root@www ~]# cd /tmp

[root@www tmp]# cp /etc/man.config .

[root@www tmp]# gzip -v man.config

man.config: 56.1% -- replaced with man.config.gz

[root@www tmp]# ll /etc/man.config /tmp/man*

-rw-r--r-- 1 root root 4617 Jan 6 2007 /etc/man.config

-rw-r--r-- 1 root root 2684 Nov 10 17:24 /tmp/man.config.back.Z

-rw-r--r-- 1 root root 2057 Nov 10 17:14 /tmp/man.config.gz <==gzip压缩比较佳

与 compress 类似的,当你使用 gzip 进行压缩时,在预设的状态下原本的档案会被压缩成为 .gz 的档名, 源文件就不再存在了。您也可以发现,由于 gzip 的压缩比要比 compress 好的多,所以当然建议使用 gzip 啦! 此外,使用 gzip 压缩的档案在 Windows 系统中,竟然可以被 WinRAR 这个软件解压缩呢!很好用吧!至于其它的用法如下:

范例二:由于 man.config 是文字文件,请将范例一的压缩文件的内容读出来!

[root@www tmp]# zcat man.config.gz

# 由于 man.config 这个原本的档案是是文字文件,因此我们可以尝试使用 zcat 去读取!

# 此时屏幕上会显示 man.config.gz 解压缩之后的档案内容!

范例三:将范例一的档案解压缩

[root@www tmp]# gzip -d man.config.gz

# 不要使用 gunzip 这个指令,不好背!使用 gzip -d 来进行解压缩!

# 与 gzip 相反, gzip -d 会将原本的 .gz 删除,产生原本的 man.config 档案。

范例四:将范例三解开的 man.config 用最佳的压缩比压缩,并保留原本的档案

[root@www tmp]# gzip -9 -c man.config > man.config.gz

其实 gzip 的压缩已经最佳化过了,所以虽然 gzip 提供 1~9 的压缩等级,不过使用预设的 6 就非常好用了! 因此上述的范例四可以不要加入那个 -9 的选项。范例四的重点在那个 -c 与 > 的使用啰!

cat 可以读取纯文字文件,那个 zcat 则可以读取纯文字文件被压缩后的压缩档!zcat 这个指令可以同时读取 compress 与 gzip 的压缩文件!

bzip2、bzcat

若说 gzip 是为了取代 compress 并提供更好的压缩比而成立的,那么 bzip2 则是为了取代 gzip 并提供更佳的压缩比而来的。

[root@www ~]# bzip2 [-cdkzv#] 档名

[root@www ~]# bzcat 档名.bz2

选项与参数:

-c :将压缩的过程产生的数据输出到屏幕上!

-d :解压缩的参数

-k :保留源文件,而不会删除原始的档案喔!

-z :压缩的参数

-v :可以显示出原档案/压缩档案的压缩比等信息;

-# :与 gzip 同样的,都是在计算压缩比的参数, -9 最佳, -1 最快!

范例一:将刚刚的 /tmp/man.config 以 bzip2 压缩

[root@www tmp]# bzip2 -z man.config

# 此时 man.config 会变成 man.config.bz2 !

范例二:将范例一的档案内容读出来!

[root@www tmp]# bzcat man.config.bz2

# 此时屏幕上会显示 man.config.bz2 解压缩之后的档案内容!!

范例三:将范例一的档案解压缩

[root@www tmp]# bzip2 -d man.config.bz2

范例四:将范例三解开的 man.config 用最佳的压缩比压缩,并保留原本的档案

[root@www tmp]# bzip2 -9 -c man.config > man.config.bz2

使用 compress 扩展名自动建立为 .Z ,使用 gzip 扩展名自动建立为 .gz 。这里的 bzip2 则是自动的将扩展名建置为 .bz2 啰!所以当我们使用具有压缩功能的 bzip2 -z 时,那么刚刚的 man.config 就会自动的变成了 man.config.bz2 这个档名啰!好了,那么如果我想要读取这个档案 的内容呢? 是否一定要解开?当然不需要啰!可以使用简便的 bzcat 这个指令来读取内容即可!例如上面的例子中, 我们可以使用 bzcat man.config.bz2 来读取数据而不需要解开!此外,当你要解开一个压缩档时,这个档案的名称为 .bz, .bz2, .tbz, .tbz2 等等,那么就可以尝试使用 bzip2 来解看看啦!当然啰,也可以使用 bunzip2 这个指令来取代 bzip2 -d 啰。

tar (打包指令)

tar 的选项与参数非常的多!我们只讲几个常用的选项,更多选项您可以自行 man tar 查询啰!

[root@www ~]# tar [-j|-z] [cv] [-f 建立的档名] filename... <==打包与压缩

[root@www ~]# tar [-j|-z] [tv] [-f 建立的档名] <==察看档名

[root@www ~]# tar [-j|-z] [xv] [-f 建立的档名] [-C 目录] <==解压缩

选项与参数:

-c :建立打包档案,可搭配 -v 来察看过程中被打包的档名(filename)

-t :察看打包档案的内容含有哪些档名,重点在察看『档名』就是了;

-x :解打包或解压缩的功能,可以搭配 -C (大写) 在特定目录解开,

特别留意的是, -c, -t, -x 不可同时出现在一串指令列中。

-j :透过 bzip2 的支持进行压缩/解压缩:此时档名最好为 *.tar.bz2

-z :透过 gzip 的支持进行压缩/解压缩:此时档名最好为 *.tar.gz

-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 欲解压缩的目录

有事没事备份一下 /etc 这个目录是件好事!备份 /etc 最简单的方法就是使用 tar 啰!让我们来玩玩先:

[root@www ~]# tar -zpcv -f /root/etc.tar.gz /etc

tar: Removing leading `/' from member names <==注意这个警告讯息

/etc/

....中间省略....

/etc/esd.conf

/etc/crontab

# 由于加上 -v 这个选项,因此正在作用中的文件名就会显示在屏幕上。

# 如果你可以翻到第一页,会发现出现上面的错误讯息!底下会讲解。

# 至于 -p 的选项,重点在于『保留原本档案的权限与属性』之意。

[root@www ~]# tar -jpcv -f /root/etc.tar.bz2 /etc

# 显示的讯息会跟上面一模一样啰!

[root@www ~]# ll /root/etc*

-rw-r--r-- 1 root root 8740252 Nov 15 23:07 /root/etc.tar.bz2

-rw-r--r-- 1 root root 13010999 Nov 15 23:01 /root/etc.tar.gz

[root@www ~]# du -sm /etc

118 /etc

# 为什么建议您使用 -j 这个选项?从上面的数值你可以知道了吧(使用bzip2)?^_^

要察看档名非常的简单!可以这样做:

[root@www ~]# tar -jtv -f /root/etc.tar.bz2

....前面省略....

-rw-r--r-- root/root 1016 2008-05-25 14:06:20 etc/dbus-1/session.conf

-rw-r--r-- root/root 153 2007-01-07 19:20:54 etc/esd.conf

-rw-r--r-- root/root 255 2007-01-06 21:13:33 etc/crontab

如果加上 -v 这个选项时,详细的档案权限/属性都会被列出来!如果只是想要知道档名而已, 那么就将 -v 拿掉即可。从上面的数据我们可以发现一件很有趣的事情,那就是每个文件名都没了根目录了!这也是上一个练习中出现的那个警告讯息『tar: Removing leading `/' from member names(移除了档名开头的 `/' )』所告知的情况!

那为什么要拿掉根目录呢?主要是为了安全!我们使用 tar 备份的数据可能会需要解压缩回来使用, 在 tar 所记录的文件名 (就是我们刚刚使用 tar -jtvf 所察看到的档名) 那就是解压缩后得实际档名。 如果拿掉了根目录,假设你将备份数据在 /tmp 解开,那么解压缩的档名就会变成『/tmp/etc/xxx』。 但『如果没有拿掉根目录,解压缩后的档名就会是绝对路径, 亦即解压缩后的数据一定会被放置到 /etc/xxx去!』如此一来,你的原本的 /etc/ 底下的数据, 就会被备份数据所覆盖过去了!

仅解开单一档案的方法

刚刚上头我们解压缩都是将整个打包档案的内容全部解开!想象一个情况,如果我只想要解开打包档案内的其中一个档案而已, 那该如何做呢?徆简单的,你只要使用 -jtv 找到你要的档名,然后将该档名解开即可。 我们用底下的例子来说明一下:

# 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 内的档名之故!

其他常见的压缩与备份工具

dd

dd 指令最大的功效,应该是在于『备份』啊! 因为 dd 可以读取磁盘装置的内容(几乎是直接读取扇区"sector"),然后将整个装置备份成一个档案呢!真的是相当的好用啊~ dd 的用途有很多啦~但是我们仅讲一些比较重要的选项,如下:

[root@www ~]# dd if="input_file" of="output_file" bs="block_size" \

> count="number"

选项与参数:

if :就是 input file 啰~也可以是装置喔!

of :就是 output file 喔~也可以是装置;

bs :规划的一个 block 的大小,若未指定则预设是 512 bytes(一个 sector 的大小)

count:多少个 bs 的意思。

范例一:将 /etc/passwd 备份到 /tmp/passwd.back 当中

[root@www ~]# dd if=/etc/passwd of=/tmp/passwd.back

3+1 records in

3+1 records out

1945 bytes (1.9 kB) copied, 0.000332893 seconds, 5.8 MB/s

[root@www ~]# ll /etc/passwd /tmp/passwd.back

-rw-r--r-- 1 root root 1945 Sep 29 02:21 /etc/passwd

-rw-r--r-- 1 root root 1945 Dec 17 18:09 /tmp/passwd.back

# 仔细的看一下,我的 /etc/passwd 档案大小为 1945 bytes,因为我没有设定 bs ,

# 所以预设是 512 bytes 为一个单位,因此,上面那个 3+1 表示有 3 个完整的

# 512 bytes,以及未满 512 bytes 的另一个 block 的意思啦!

# 事实上,感觉好像是 cp 这个指令啦~

范例二:将自己的磁盘之第一个扇区备份下来

[root@www ~]# dd if=/dev/hdc of=/tmp/mbr.back bs=512 count=1

1+0 records in

1+0 records out

512 bytes (512 B) copied, 0.0104586 seconds, 49.0 kB/s

# 第一个扇区内含有 MBR 与 partition table ,透过这个动作,

# 我们可以一口气将这个磁盘的 MBR 与 partition table 进行备份哩!

范例三:找出你系统最小的那个分割槽,并且将他备份下来:

[root@www ~]# df -h

Filesystem Size Used Avail Use% Mounted on

/dev/hdc2 9.5G 3.9G 5.1G 44% /

/dev/hdc3 4.8G 651M 3.9G 15% /home

/dev/hdc1 99M 21M 73M 23% /boot <==就做他好了!

[root@www ~]# dd if=/dev/hdc1 of=/tmp/boot.whole.disk

208782+0 records in

208782+0 records out

106896384 bytes (107 MB) copied, 6.24721 seconds, 17.1 MB/s

[root@www ~]# ll -h /tmp/boot.whole.disk

-rw-r--r-- 1 root root 102M Dec 17 18:14 /tmp/boot.whole.disk

# 等于是将整个 /dev/hdc1 通通捉下来的意思~如果要还原呢?就反向回去!

# dd if=/tmp/boot.whole.disk of=/dev/hdc1 即可!非常简单吧!

# 简单的说,如果想要整个硬盘备份的话,就类似 Norton 的 ghost 软件一般,

# 由 disk 到 disk ,嘿嘿~利用 dd 就可以啦~厉害厉害!

你可以说, tar 可以用来备份关键数据,而 dd 则可以用来备份整颗 partition 或整颗 disk ,很不错啊~不过,如果要将数据填回到 filesystem 当中,可能需要考虑到原本的 filesystem 才能成功啊!

cpio

这个指令挺有趣的,因为 cpio 可以备份任何东西,包括装置设备档案。不过 cpio 有个大问题, 那就是 cpio 不会主动的去找档案来备份!所以,一般来说, cpio 得要配合类似 find 等可以找到文件名的指令来告知 cpio 该被备份的数据在哪里啊! 有点小麻烦啦~因为牵涉到我们在第三篇才会谈到的数据流重导向说~ 所以这里你就先背一下语法,等到第三篇讲完你就知道如何使用 cpio 啰!

[root@www ~]# cpio -ovcB > [file|device] <==备份

[root@www ~]# cpio -ivcdu < [file|device] <==还原

[root@www ~]# cpio -ivct < [file|device] <==察看

备份会使用到的选项与参数:

-o :将数据 copy 输出到档案或装置上

-B :让预设的 Blocks 可以增加至 5120 bytes ,预设是 512 bytes !

    这样的好处是可以让大档案的储存速度加快(请参考 i-nodes 的观念)

还原会使用到的选项与参数:

-i :将数据自档案或装置 copy 出来系统当中

-d :自动建立目录!使用 cpio 所备份的数据内容不见得会在同一层目录中,因此我们必须要让 cpio 在还原时可以建立新目录,此时就得要 -d 选项的帮助!

-u :自动的将较新的档案覆盖较旧的档案!

-t :需配合 -i 选项,可用在"察看"以 cpio 建立的档案或装置的内容一些可共享的选项与参数:

-v :让储存的过程中文件名称可以在屏幕上显示

-c :一种较新的 portable format 方式储存

你应该会发现一件事情,就是上述的选项与指令中怎么会没有指定需要备份的数据呢?还有那个大于 (>) 与小于 (<) 符号是怎么回事啊?因为 cpio 会将数据整个显示到屏幕上,因此我们可以透过将这些屏幕的数据重新导向 (>) 一个新的档案! 至于还原呢?就是将备份文件读进来 cpio (<) 进行处理之意!我们来进行几个案例你就知道啥是啥了!

范例:找出 /boot 底下的所有档案,然后将他备份到 /tmp/boot.cpio 去!

[root@www ~]# find /boot -print

/boot

/boot/message

/boot/initrd-2.6.18-128.el5.img

....以下省略....

# 透过这个 find 我们可以找到 /boot 底下应该要存在的档名!包括档案与目录

[root@www ~]# find /boot | cpio -ocvB > /tmp/boot.cpio

[root@www ~]# ll -h /tmp/boot.cpio

-rw-r--r-- 1 root root 16M Dec 17 23:30 /tmp/boot.cpio

我们使用 find /boot 可以找出档名,然后透过那条管线 (|, 亦即键盘上的 shift+\ 的组合), 就能将档名传给 cpio 来进行处理!最终会得到 /tmp/boot.cpio 那个档案喔!接下来让我们来进行解压缩看看。

范例:将刚刚的档案给他在 /root/ 目录下解开

[root@www ~]# cpio -idvc < /tmp/boot.cpio

[root@www ~]# ll /root/boot

# 你可以自行比较一下 /root/boot 与 /boot 的内容是否一模一样!

事实上 cpio 可以将系统的数据完整的备份到磁带机上头去喔!如果你有磁带机的话!

备份:find / | cpio -ocvB > /dev/st0

还原:cpio -idvc < /dev/st0

这个cpio 好像不怎么好用呦!但是,他可是备份的时候的一项利器呢!因为他可以备份任何的档案, 包括 /dev 底下的任何装置档案!所以他可是相当重要的呢!而由于 cpio 必需要配合其它的程序,例如 find 来建立档名,所以 cpio 与管线命令及数据流重导向的相关性就相当的重要了!

其实系统里面已经含有一个使用 cpio 建立的档案喔!那就是 /boot/initrd-xxx 这个档案啦! 现在让我们来将这个档案解压缩看看,看你能不能发现该档案的内容为何?

# 1. 我们先来看看该档案是属于什么档案格式,然后再加以处理:

[root@www ~]# file /boot/initrd-2.6.18-128.el5.img

/boot/initrd-2.6.18-128.el5.img: gzip compressed data, ...

# 唔!看起来似乎是使用 gzip 进行压缩过~那如何处理呢?

# 2. 透过更名,将该档案增加扩展名,然后予以解压缩看看:

[root@www ~]# mkdir initrd

[root@www ~]# cd initrd

[root@www initrd]# cp /boot/initrd-2.6.18-128.el5.img initrd.img.gz

[root@www initrd]# gzip -d initrd.img.gz

[root@www initrd]# ll

-rw------- 1 root root 5408768 Dec 17 23:53 initrd.img

[root@www initrd]# file initrd.img

initrd.img: ASCII cpio archive (SVR4 with no CRC)

# 嘿嘿!露出马脚了吧!确实是 cpio 的文件档喔!

# 3. 开始使用 cpio 解开此档案:

[root@www initrd]# cpio -iduvc < initrd.img

sbin

init

sysroot

....以下省略....

# 瞧!这样就将这个档案解开啰!这样了解乎?

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: