D15:常见任务和基本工具之五
归档和备份
本章涉及的命令有:
文件压缩程序:
gzip —— 压缩或解压文件
bzip2 —— 块排序文件压缩
归档程序:
tar —— 磁带存档实用程序
zip —— 打包和压缩文件
文件同步程序:
rsync —— 远程文件和目录同步
目录:
压缩文件
数据压缩是从数据中消除冗余的过程。压缩算法(用于执行压缩的数学技术)分为两大类:
无损(Lossless)
无损压缩保留原始文件中包含的所有数据。
有损(Lossy)
允许对更多有损数据进行压缩。比如JPEG和MP3。
由于计算机上大多数数据都不能容忍任何数据丢失,所以这里只研究无损压缩。
gzip
gzip 程序用于压缩一个或多个文件。执行时,它会将原始文件替换为原始文件的压缩版本。
相应的,gunzip 程序用于将压缩文件恢复为原始的未压缩形式。
举例:
[me@linuxbox ~]$ ls -l /etc > foo.txt
[me@linuxbox ~]$ ls -l foo.*
-rw-r--r-- 1 me me 15738 2018-10-14 07:15 foo.txt
[me@linuxbox ~]$ gzip foo.txt
[me@linuxbox ~]$ ls -l foo.*
-rw-r--r-- 1 me me 3230 2018-10-14 07:15 foo.txt.gz
[me@linuxbox ~]$ gunzip foo.txt
[me@linuxbox ~]$ ls -l foo.*
-rw-r--r-- 1 me me 15738 2018-10-14 07:15 foo.txt
gzip 常用选项:
选项
长选项
说明
-c
--stdout --to-stdout
将输出写入标准输出并保留原始文件。
-d
--decompress --uncompress
解压缩。与使用gunzip 相似。
-f
--force
即使原始文件的压缩版本已经存在,也要强制压缩。
-h
--help
显示使用帮助。
-l
--list
列出每个压缩文件的压缩统计信息
-r
--recursive
如果命令行上的一个或多个参数是目录,则递归压缩其中包含的文件。
-t
--test
测试压缩文件的完整性。
-v
--verbose
压缩时显示详细消息。
-number
设置压缩量。
number 介于1(最快、压缩比最小)到9(最慢、压缩比最大)之间。值1和9也可以分别替代为--fast和--best。
默认值为6。
gzip 可以通过标准输入和输出以有趣的方式使用:
[me@linuxbox ~]$ ls -s /etc | gzip > foo.txt.gz
以上命令可以直接生成压缩过的文件。
gzip 和gunzip 假定文件名以扩展名.gz结尾,因此无需指定它,只要指定的名称与现有的解压缩文件不冲突。
如果只是要查看压缩文本文件的内容,可以使用以下命令:
[me@linuxbox ~]$ gunzip -c foo.txt | less
或者可以使用gzip 提供的一个名为zcat 的程序,它相当于带了-c 选项的gunzip 。它可以像cat 命令一样用于gzip压缩文件:
[me@linuxbox ~]$ zcat foo.txt.gz | less
另外还有一个zless 程序可以实现类似的效果。
bzip2
Julian Seward写的bzip2程序与gzip类似,但使用了不同的压缩算法,以牺牲压缩速度为代价实现更高的压缩比。
大多数情况下,它的工作方式与gzip 相同。
用bzip2 压缩的文件扩展名为.bz2。
[me@linuxbox ~]$ ls -l /etc > foo.txt
[me@linuxbox ~]$ ls -l foo.txt
-rw-r--r-- 1 me me 15738 2018-10-17 13:51 foo.txt
[me@linuxbox ~]$ bzip2 foo.txt
[me@linuxbox ~]$ ls -l foo.txt.bz2
-rw-r--r-- 1 me me 2792 2018-10-17 13:51 foo.txt.bz2
[me@linuxbox ~]$ bunzip2 foo.txt.bz2
bzip2 不支持-r 选项,且-number 的含义与gzip 有些差异。
bzip2 附带用于解压缩文件的bunzip2 和bcat 。
bzip2 还附带了bz2recover 程序,用于尝试修复损坏的bz2文件。
不要强迫自己
对已经压缩过的文件进行压缩,通常会得到更大的文件。
归档文件
归档通常与压缩结合使用。
归档将许多文件收集起来,并将它们捆绑到一个大文件中。
tar
tar是tape archive(磁带存档)的缩写。
一般来说,扩展名为.tar的文件表示普通tar存档;扩展名.tgz表示gzip存档。
tar存档可以由一组单独的文件、一个或多个目录层次结构或两者的混合组成。
语法如下:
tar mode [optinos ] pathname ...
mode 可以是以下之一:
模式
解释
c
从文件和/或目录列表创建归档
x
提取归档文件
r
将指定的路径名附加到归档的末尾
t
列出归档的包含的内容
举例:
[me@linuxbox ~]$ mkdir -p playground/dir-{001..100}
[me@linuxbox ~]$ touch playground/dir-{001..100}/file-{A..Z}
然后,创建一个归档:
[me@linuxbox ~]$ tar cf playground.tar playground
此命令创建一个名为playground.tar的归档文件,它包含整个playground目录层次结构。mode c和option f连在一起,中间没有破折号。
但是需要注意,mode 必须在前面,然后才能指定其他选项。
要查看归档包里的内容,可以使用以下命令:
[me@linuxbox ~]$ tar tf playground.tar
添加v 选项可以查看更详细信息:
[me@linuxbox ~]$ tar tvf playground.tar
下面将归档的文件解出至新的地方:
[me@linuxbox ~]$ mkdir foo
[me@linuxbox ~]$ cd foo
[me@linuxbox foo]$ tar xf ../playground.tar
[me@linuxbox foo]$ ls
playground
通常路径名不支持通配符,但是提供了--wildcards 选项可以使用通配符(FreeBSD中无此选项 ):
[me@linuxbox ~]$ tar xf ../playgound2.tar --wildcards 'home/me/playground/dir-*/file-A'
以上命令仅释放匹配指定路径的文件。
tar 经常与find 结合使用以生成档案:
[me@linuxbox ~]$ find playground -name 'file-A' -exec tar rf playground.tar '{}' '+'
以上示例使用find 生成一组要包含在归档文件中的文件。
在find 中使用tar 是创建目录树或整个系统的增量备份(incremental backups)的好方法。
通过使用find -newer timestamp -exec tar rf test.tar '{}' '+' 来匹配比“timestamp”新的文件,可以创建一个只包含比上一个归档文件新的文件的归档文件。
tar 还可以使用标准输入和输出。下面是一个全面的例子:
[me@linuxbox foo]$ cd
[me@linuxbox ~]$ find playground -name 'file-A' | tar cf - --files-from=- | gzip > playground.tgz
此例中,使用find 程序生成匹配文件的列表,并将它们传输到tar 中。
如果指定了文件名-,则根据需要将其视为标准输入或输出。(使用-来表示标准输入/输出的管理也被其他程序使用)
--files-from 选项(也可以指定为-T )使tar 从文件而不是命令读取其路径名列表。
最后,tar 生成的归档文件通过管道传输到gzip 中,以创建压缩的归档文件playground.tgz。
.tgz扩展名是gzip压缩tar文件的常规扩展名。有时候也会使用.tar.gz扩展名。
虽然可以在外部使用gzip 程序来生成压缩的归档文件,但GNUtar 的现代版本分别使用z 和j 选项直接支持gzip 和bzip2 压缩。
前面的例子可以简化为:
[me@linuxbox ~]$ find playground -name 'file-A' | tar czf playground.tgz -T -
以下是使用bzip2压缩的示例:
[me@linuxbux ~]$ find playground -name 'file-A' | tar cjf playground.tbz -T -
tar 命令的标准输入和输出的另一个有趣用法是通过网络在系统中传输文件:
[me@linuxbox ~]$ mkdir remote-stuff
[me@linuxbox ~]$ cd remote-stuff
[me@linuxbox remote-stuff]$ ssh remote-sys 'tar cf - Documents' | tar xf -
me@remote-sys’s password:
[me@linuxbox remote-stuff]$ ls
Documents
zip
zip/unzip 的主要用途时与Windows系统交换文件,而不是在Linux上执行压缩和归档,在Linux上,tar 和gzip 才是首选。
基本格式(FreeBSD默认没有此软件,需要安装):
zip options zipfile file ...
例如:
[me@linuxbox ~]$ zip -r playground.zip playground
如果没有包含递归选项-r ,则只存储目录而不存储其中的内容。
虽然扩展名.zip会自动添加,但为清晰起见,最好能添加文件扩展名。
创建zip压缩文件时,zip 通常会显示一系列消息:
adding: playground/dir-020/file-Z (stored 0%)
adding: playground/dir-020/file-Y (stored 0%)
adding: playground/dir-020/file-X (stored 0%)
adding: playground/dir-087/ (stored 0%)
adding: playground/dir-087/file-S (stored 0%)
使用unzip 可以很简单的解压缩文件:
[me@linuxbox ~]$ cd foo
[me@linuxbox foo]$ unzip ../playground.zip
与tar 相反,zip 如果指定了现有的归档文件,它将会被更新而不是替换。
通过指定要解压的文件,可以有选择地从zip文件中列出和提取文件:
[me@linuxbox ~]$ unzip -l playground.zip playground/dir-087/file-Z
Archive: ../playground.zip
Length Date Time Name
-------- ---- ---- ----
0 10-05-16 09:25 playground/dir-087/file-Z
-------- -------
0 1 file
[me@linuxbox ~]$ cd foo
[me@linuxbox foo]$ unzip ../playground.zip playground/dir-087/file-Z
Archive: ../playground.zip
replace playground/dir-087/file-Z? [y]es, [n]o, [A]ll, [N]one,
[r]ename: y
extracting: playground/dir-087/file-Z
使用-l 选项会导致unzip 只列出归档文件的内容,而不提取文件。如果未指定任何文件,unzip 将列出存档中的所有文件。
可以添加-v 选项来增加列表的详细程度。
当存档提取与现有文件冲突时,会在替换文件之前提示用户。
与tar 一样,zip 可以使用标准的输入和输出。可以通过-@ 选项将文件名列表传输到zip :
[me@linuxbox foo]$ cd
[me@linuxbox ~]$ find playground -name "file-A" | zip -@ file-A.zip
以上,使用find 生成一个与测试名称“file-A”匹配的文件列表,然后将该列表导入zip ,这将创建包含所选文件的存档“file-A.zip”。
zip 还支持将其输出写入标准输出,但它的使用受到限制,因为几乎没有程序可以使用该输出。
不幸的是,unzip 不接受标准输入。这可以防止zip 和unzip 一起用于像tar 一样执行网络文件复制。
然而,zip 可以接受标准输入,因此可以用来压缩其他程序的输出:
[me@linuxbox ~]$ ls -l /etc/ | zip ls-etc.zip -
adding: - (deflated 80%)
以上例子中,通过管道将ls 的输出传输到zip 中。和tar 一样,zip 将尾随的破折号解释为“对输入文件使用标准输入”。
当指定-p (pipe管道)选项时,unzip 允许将其输出发送到标准输出:
[me@linuxbox ~]$ unzip -p ls-etc.zip | less
同步文件和目录
rsync 命令的格式为:
rsync options source destination
source 和destination 可以是以下一种:
本地文件或目录
以[user@]host:path 格式的远程文件或目录
以URLrsync://[user@]host[:port}/path 指定的远程rsync服务器
注意:源文件或目标文件必须有一个是本地文件,不支持远程到远程复制 。
以下命令将playground目录对应的副本同步到foo目录中:
[me@linuxbox ~]$ rsync -av playground foo
其中-a 选项用于归档——导致文件属性的递归和保存,-v 选项表示详细输出(verbose output)。
当命令运行时,我们将看到被复制的文件和目录的列表,以及复制数量的摘要信息。
如果我们再执行一次,结果会有不同:
[me@linuxbox ~]$ rsync -av playground foo
building file list ... done
sent 22635 bytes received 20 bytes 45310.00 bytes/sec
total size is 3230 speedup is 0.14
没有显示文件,这是因为rsync 检测到~/playground 和~/foo/playground 这两个目录完全相同,不需要复制任何文件。
如果我们修改一个playground 中的文件,然后再运行rsync :
[me@linuxbox ~]$ touch playground/dir-099/file-Z
[me@linuxbox ~]$ rsync -av playground foo
building file list ... done
playground/dir-099/file-Z
sent 22685 bytes received 42 bytes 45454.00 bytes/sec
total size is 3230 speedup is 0.14
可以看到,rsync 检测到变化并仅仅复制了更新的文件。
如果source 后面带斜杠,则rsync 仅复制源目录中的内容,而不复制源目录。例如:
[me@linuxbox ~]$ rsync source/ destination
而如果使用source/*,则复制源目录中的所有内容,包括隐藏的文件。
以下示例将重要内容同步到移动硬盘的backup目录:
[me@linuxbox ~]$ mkdir /media/BigDisk/backup
[me@linuxbox ~]$ sudo rsync -av --delete /etc /home /usr/local
/media/BigDisk/backup
以上示例将/etc、/home、/usr/local目录从系统复制到虚拟存储设备。
--delete 选项用于删除备份设备上可能存在但源设备上不再存在的文件。
这种方法可以用来备份小型系统,也可以通过在.bashrc文件中创建别名来简化操作:
alias backup='sudo rsync -av --delete /etc /home /usr/local /media/BigDisk/backup'
然后运行backup 即可。
在网络上使用rsync
rsync 真正的优点之一是它可以通过网络复制文件。
实现远程复制的第一种方法是通过ssh完成远程复制。
以下例子假设远程主机名为remote-sys,其上有个名为/backup的目录:
[me@linuxbox ~]$ sudo rsync -av --delete --rsh=ssh /etc /home /usr/local remote-sys:/backup
--rsh=ssh 选项告诉rsync 命令使用ssh 程序作为它的远程shell。此时,可以使用ssh加密通道安全传输数据到远程主机。
remote-sys:/backup 则表示远程主机上的路径名。
第二种方法是通过rsync server 来实现网络数据同步。
rsync 可以以进程方式运行并监听同步传入请求。这样做通常是为了允许对远程系统进行镜像。
举例:
[me@linuxbox ~]$ mkdir fedora-devel
[me@linuxbox ~]$ rsync -av --delete rsync://archive.linux.duke.edu/fedora/linux/development/rawhide/Everything/x86_64/os/ fedora-devel
2022/3/2
回主站 回目录
e-mail & paypal:il.gnepad@gnepadil