geekdoc-linux-zh/docs/linux-cli/linux-cli_19.md

463 lines
28 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 归档和备份
layout: book-zh
## title: 归档和备份
计算机系统管理员的一个主要任务就是保护系统的数据安全。一种方法是通过时时备份系统文件,来保护 数据。即使你不是一名系统管理员,复制东西,在各个位置和设备之间移动大量的文件,也是很有帮助的。 在这一章中,我们将会看看几个经常用来管理文件集合的程序。它们就是文件压缩程序:
* gzip 压缩或者展开文件
* bzip2 块排序文件压缩器
归档程序:
* tar 磁带打包工具
* zip 打包和压缩文件
还有文件同步程序:
* rsync 同步远端文件和目录
### 压缩文件
纵观计算领域的发展历史,人们努力想把最多的数据存放到到最小的可用空间中,不管是内存,存储设备 还是网络带宽。今天我们把许多数据服务都看作是理所当然的事情,但是诸如便携式音乐播放器, 高清电视,或宽带网络之类的存在都应归功于高效的数据压缩技术。
数据压缩就是一个删除冗余数据的过程。让我们考虑一个假想的例子,比方说我们有一张 100*100 像素的 纯黑的图片文件。根据数据存储方案(假定每个像素占 24 位,或者 3 个字节),那么这张图像将会占用 30,000 个字节的存储空间:
```
100 * 100 * 3 = 30,000
```
一张单色图像包含的数据全是多余的。我们要是聪明的话,可以用这种方法来编码这些数据, 我们只要简单地描述这个事实,我们有 3 万个黑色的像素数据块。所以,我们不存储包含 3 万个 0 (通常在图像文件中,黑色由 0 来表示)的数据块,取而代之,我们把这些数据压缩为数字 30,000 后跟一个 0来表示我们的数据。这种数据压缩方案被称为游程编码是一种最基本的压缩技术。
压缩算法(数学技巧被用来执行压缩任务)分为两大类,无损压缩和有损压缩。无损压缩保留了 原始文件的所有数据。这意味着,当还原一个压缩文件的时候,还原的文件与原文件一模一样。 而另一方面,有损压缩,执行压缩操作时会删除数据,允许更大的压缩。当一个有损文件被还原的时候, 它与原文件不相匹配; 相反,它是一个近似值。有损压缩的例子有 JPEG图像文件和 MP3音频文件。 在我们的讨论中,我们将看看完全无损压缩,因为计算机中的大多数数据是不能容忍丢失任何数据的。
这个 gzip 程序被用来压缩一个或多个文件。当执行 gzip 命令时,则原始文件的压缩版会替代原始文件。 相对应的 gunzip 程序被用来把压缩文件复原为没有被压缩的版本。这里有个例子:
```
[me@linuxbox ~]$ ls -l /etc > foo.txt
[me@linuxbox ~]$ ls -l foo.*
-rw-r--r-- 1 me me 15738 2008-10-14 07:15 foo.txt
[me@linuxbox ~]$ gzip foo.txt
[me@linuxbox ~]$ ls -l foo.*
-rw-r--r-- 1 me me 3230 2008-10-14 07:15 foo.txt.gz
[me@linuxbox ~]$ gunzip foo.txt
[me@linuxbox ~]$ ls -l foo.*
-rw-r--r-- 1 me me 15738 2008-10-14 07:15 foo.txt
```
在这个例子里,我们创建了一个名为 foo.txt 的文本文件,其内容包含一个目录的列表清单。 接下来,我们运行 gzip 命令,它会把原始文件替换为一个叫做 foo.txt.gz 的压缩文件。在 foo.*文件列表中,我们看到原始文件已经被压缩文件替代了,并将这个压缩文件大约是原始 文件的十五分之一。我们也能看到压缩文件与原始文件有着相同的权限和时间戳。
接下来,我们运行 gunzip 程序来解压缩文件。随后,我们能见到压缩文件已经被原始文件替代了, 同样地保留了相同的权限和时间戳。
gzip 命令有许多选项。这里列出了一些:
表 19-1: gzip 选项
| 选项 | 说明 |
| -c | 把输出写入到标准输出,并且保留原始文件。也有可能用--stdout 和--to-stdout 选项来指定。 |
| -d | 解压缩。正如 gunzip 命令一样。也可以用--decompress 或者--uncompress 选项来指定. |
| -f | 强制压缩,即使原始文件的压缩文件已经存在了,也要执行。也可以用--force 选项来指定。 |
| -h | 显示用法信息。也可用--help 选项来指定。 |
| -l | 列出每个被压缩文件的压缩数据。也可用--list 选项。 |
| -r | 若命令的一个或多个参数是目录,则递归地压缩目录中的文件。也可用--recursive 选项来指定。 |
| -t | 测试压缩文件的完整性。也可用--test 选项来指定。 |
| -v | 显示压缩过程中的信息。也可用--verbose 选项来指定。 |
| -number | 设置压缩指数。number 是一个在 1最快最小压缩到 9最慢最大压缩之间的整数。 数值 1 和 9 也可以各自用--fast 和--best 选项来表示。默认值是整数 6。 |
返回到我们之前的例子中:
```
[me@linuxbox ~]$ gzip foo.txt
[me@linuxbox ~]$ gzip -tv foo.txt.gz
foo.txt.gz: OK
[me@linuxbox ~]$ gzip -d foo.txt.gz
```
这里,我们用压缩文件来替代文件 foo.txt压缩文件名为 foo.txt.gz。下一步我们测试了压缩文件 的完整性,使用了-t 和-v 选项。
```
[me@linuxbox ~]$ ls -l /etc | gzip > foo.txt.gz
```
这个命令创建了一个目录列表的压缩文件。
这个 gunzip 程序,会解压缩 gzip 文件,假定那些文件名的扩展名是.gz所以没有必要指定它 只要指定的名字与现有的未压缩文件不冲突就可以:
```
[me@linuxbox ~]$ gunzip foo.txt
```
如果我们的目标只是为了浏览一下压缩文本文件的内容,我们可以这样做:
```
[me@linuxbox ~]$ gunzip -c foo.txt | less
```
另外,对应于 gzip 还有一个程序,叫做 zcat它等同于带有-c 选项的 gunzip 命令。 它可以被用来如 cat 命令作用于 gzip 压缩文件:
```
[me@linuxbox ~]$ zcat foo.txt.gz | less
```
* * *
*小贴士:* 还有一个 zless 程序。它与上面的管道线有相同的功能。
* * *
这个 bzip2 程序,由 Julian Seward 开发,与 gzip 程序相似,但是使用了不同的压缩算法, 舍弃了压缩速度,而实现了更高的压缩级别。在大多数情况下,它的工作模式等同于 gzip。 由 bzip2 压缩的文件,用扩展名 .bz2 来表示:
```
[me@linuxbox ~]$ ls -l /etc > foo.txt
[me@linuxbox ~]$ ls -l foo.txt
-rw-r--r-- 1 me me 15738 2008-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 2008-10-17 13:51 foo.txt.bz2
[me@linuxbox ~]$ bunzip2 foo.txt.bz2
```
正如我们所看到的bzip2 程序使用起来和 gzip 程序一样。我们之前讨论的 gzip 程序的所有选项(除了-r bzip2 程序同样也支持。注意,然而,压缩级别选项(-number对于 bzip2 程序来说,有少许不同的含义。 伴随着 bzip2 程序,有 bunzip2 和 bzcat 程序来解压缩文件。bzip2 文件也带有 bzip2recover 程序,其会 试图恢复受损的.bz2 文件。
> 不要强迫性压缩
>
> 我偶然见到人们试图用高效的压缩算法,来压缩一个已经被压缩过的文件,通过这样做:
>
> *$ gzip picture.jpg*
>
> 不要这样。你可能只是在浪费时间和空间!如果你再次压缩已经压缩过的文件,实际上你 会得到一个更大的文件。这是因为所有的压缩技术都会涉及一些开销,文件中会被添加描述 此次压缩过程的信息。如果你试图压缩一个已经不包含多余信息的文件,那么再次压缩不会节省 空间,以抵消额外的花费。 {: .single}
### 归档文件
一个常见的,与文件压缩结合一块使用的文件管理任务是归档。归档就是收集许多文件,并把它们 捆绑成一个大文件的过程。归档经常作为系统备份的一部分来使用。当把旧数据从一个系统移到某 种类型的长期存储设备中时,也会用到归档程序。
在类似于 Unix 的软件世界中,这个 tar 程序是用来归档文件的经典工具。它的名字,是 tape archive 的简称,揭示了它的根源,它是一款制作磁带备份的工具。而它仍然被用来完成传统任务, 它也同样适用于其它的存储设备。我们经常看到扩展名为.tar 或者.tgz 的文件,它们各自表示“普通” 的 tar 包和被 gzip 程序压缩过的 tar 包。一个 tar 包可以由一组独立的文件,一个或者多个目录,或者 两者混合体组成。命令语法如下:
这里的 mode 是指以下操作模式(这里只展示了一部分,查看 tar 的手册来得到完整列表)之一:
表 19-2: tar 模式
| 模式 | 说明 |
| c | 为文件和/或目录列表创建归档文件。 |
| x | 抽取归档文件。 |
| r | 追加具体的路径到归档文件的末尾。 |
| t | 列出归档文件的内容。 |
tar 命令使用了稍微有点奇怪的方式来表达它的选项,所以我们需要一些例子来展示它是 怎样工作的。首先,让我们重新创建之前我们用过的操练场:
```
[me@linuxbox ~]$ mkdir -p playground/dir-{00{1..9},0{10..99},100}
[me@linuxbox ~]$ touch playground/dir-{00{1..9},0{10..99},100}/file-{A-Z}
```
下一步,让我们创建整个操练场的 tar 包:
```
[me@linuxbox ~]$ tar cf playground.tar playground
```
这个命令创建了一个名为 playground.tar 的 tar 包,其包含整个 playground 目录层次结果。我们 可以看到模式 c 和选项 f其被用来指定这个 tar 包的名字,模式和选项可以写在一起,而且不 需要开头的短横线。注意,然而,必须首先指定模式,然后才是其它的选项。
要想列出归档文件的内容,我们可以这样做:
```
[me@linuxbox ~]$ tar tf playground.tar
```
为了得到更详细的列表信息,我们可以添加选项 v
```
[me@linuxbox ~]$ tar tvf playground.tar
```
现在,抽取 tar 包 playground 到一个新位置。我们先创建一个名为 foo 的新目录,更改目录, 然后抽取 tar 包中的文件:
```
[me@linuxbox ~]$ mkdir foo
[me@linuxbox ~]$ cd foo
[me@linuxbox ~]$ tar xf ../playground.tar
[me@linuxbox ~]$ ls
playground
```
如果我们检查~/foo/playground 目录中的内容,会看到这个归档文件已经被成功地安装了,就是创建了 一个精确的原始文件的副本。有一个警告,然而:除非你是超级用户,要不然从归档文件中抽取的文件 和目录的所有权由执行此复原操作的用户所拥有,而不属于原始所有者。
tar 命令另一个有趣的行为是它处理归档文件路径名的方式。默认情况下,路径名是相对的,而不是绝对 路径。当创建归档文件的时候tar 命令会简单地删除路径名开头的斜杠。为了说明问题,我们将会 重新创建我们的归档文件,这次指定一个绝对路径:
```
[me@linuxbox foo]$ cd
[me@linuxbox ~]$ tar cf playground2.tar ~/playground
```
记住,当按下回车键后,~/playground 会展开成/home/me/playground所以我们将会得到一个 绝对路径名。接下来,和之前一样我们会抽取归档文件,观察发生什么事情:
```
[me@linuxbox ~]$ cd foo
[me@linuxbox foo]$ tar xf ../playground2.tar
[me@linuxbox foo]$ ls
home playground
[me@linuxbox foo]$ ls home
me
[me@linuxbox foo]$ ls home/me
playground
```
这里我们看到当我们抽取第二个归档文件时,它重新创建了 home/me/playground 目录, 相对于我们当前的工作目录,~/foo而不是相对于 root 目录,作为带有绝对路径名的案例。 这看起来似乎是一种奇怪的工作方式,但事实上这种方式很有用,因为这样就允许我们抽取文件 到任意位置,而不是强制地把抽取的文件放置到原始目录下。加上 verbosev选项重做 这个练习,将会展现更加详细的信息。
让我们考虑一个假设tar 命令的实际应用。假定我们想要复制主目录及其内容到另一个系统中, 并且有一个大容量的 USB 硬盘,可以把它作为传输工具。在现代 Linux 系统中, 这个硬盘会被“自动地”挂载到/media 目录下。我们也假定硬盘中有一个名为 BigDisk 的逻辑卷。 为了制作 tar 包,我们可以这样做:
```
[me@linuxbox ~]$ sudo tar cf /media/BigDisk/home.tar /home
```
tar 包制作完成之后,我们卸载硬盘,然后把它连接到第二个计算机上。再一次,此硬盘被 挂载到/media/BigDisk 目录下。为了抽取归档文件,我们这样做:
```
[me@linuxbox2 ~]$ cd /
[me@linuxbox2 /]$ sudo tar xf /media/BigDisk/home.tar
```
值得注意的一点是,因为归档文件中的所有路径名都是相对的,所以首先我们必须更改目录到根目录下, 这样抽取的文件路径就相对于根目录了。
当抽取一个归档文件时,有可能限制从归档文件中抽取什么内容。例如,如果我们想要抽取单个文件, 可以这样实现:
```
tar xf archive.tar pathname
```
通过给命令添加末尾的路径名tar 命令就只会恢复指定的文件。可以指定多个路径名。注意 路径名必须是完全的,精准的相对路径名,就如存储在归档文件中的一样。当指定路径名的时候, 通常不支持通配符然而GNU 版本的 tar 命令(在 Linux 发行版中最常出现)通过--wildcards 选项来 支持通配符。这个例子使用了之前 playground.tar 文件:
```
[me@linuxbox ~]$ cd foo
[me@linuxbox foo]$ tar xf ../playground2.tar --wildcards 'home/me/playground/dir-*/file-A'
```
这个命令将只会抽取匹配特定路径名的文件,路径名中包含了通配符 dir-*。
tar 命令经常结合 find 命令一起来制作归档文件。在这个例子里,我们将会使用 find 命令来 产生一个文件集合,然后这些文件被包含到归档文件中。
```
[me@linuxbox ~]$ find playground -name 'file-A' -exec tar rf playground.tar '{}' '+'
```
这里我们使用 find 命令来匹配 playground 目录中所有名为 file-A 的文件,然后使用-exec 行为,来 唤醒带有追加模式r的 tar 命令,把匹配的文件添加到归档文件 playground.tar 里面。
使用 tar 和 find 命令,来创建逐渐增加的目录树或者整个系统的备份,是个不错的方法。通过 find 命令匹配新于某个时间戳的文件,我们就能够创建一个归档文件,其只包含新于上一个 tar 包的文件, 假定这个时间戳文件恰好在每个归档文件创建之后被更新了。
tar 命令也可以利用标准输出和输入。这里是一个完整的例子:
```
[me@linuxbox foo]$ cd
[me@linuxbox ~]$ find playground -name 'file-A' | tar cf - --files-from=-
| gzip > playground.tgz
```
在这个例子里面,我们使用 find 程序产生了一个匹配文件列表,然后把它们管道到 tar 命令中。 如果指定了文件名“-”,则其被看作是标准输入或输出,正是所需(顺便说一下,使用“-”来表示 标准输入/输出的惯例,也被大量的其它程序使用)。这个--file-from 选项(也可以用-T 来指定) 导致 tar 命令从一个文件而不是命令行来读入它的路径名列表。最后,这个由 tar 命令产生的归档 文件被管道到 gzip 命令中,然后创建了压缩归档文件 playground.tgz。此.tgz 扩展名是命名 由 gzip 压缩的 tar 文件的常规扩展名。有时候也会使用.tar.gz 这个扩展名。
虽然我们使用 gzip 程序来制作我们的压缩归档文件,但是现在的 GUN 版本的 tar 命令 gzip 和 bzip2 压缩两者都直接支持,各自使用 z 和 j 选项。以我们之前的例子为基础, 我们可以这样简化它:
```
[me@linuxbox ~]$ find playground -name 'file-A' | tar czf playground.tgz -T -
```
如果我们本要创建一个由 bzip2 压缩的归档文件,我们可以这样做:
```
[me@linuxbox ~]$ find playground -name 'file-A' | tar cjf playground.tbz -T -
```
通过简单地修改压缩选项,把 z 改为 j并且把输出文件的扩展名改为.tbz来指示一个 bzip2 压缩文件), 就使 bzip2 命令压缩生效了。另一个 tar 命令与标准输入和输出的有趣使用,涉及到在系统之间经过 网络传输文件。假定我们有两台机器,每台都运行着类似于 Unix且装备着 tar 和 ssh 工具的操作系统。 在这种情景下,我们可以把一个目录从远端系统(名为 remote-sys传输到我们的本地系统中
```
[me@linuxbox ~]$ mkdir remote-stuff
[me@linuxbox ~]$ cd remote-stuff
[me@linuxbox remote-stuff]$ ssh remote-sys 'tar cf - Documents' | tar xf -
me@remote-syss password:
[me@linuxbox remote-stuff]$ ls
Documents
```
这里我们能够从远端系统 remote-sys 中复制目录 Documents 到本地系统名为 remote-stuff 目录中。 我们怎样做的呢?首先,通过使用 ssh 命令在远端系统中启动 tar 程序。你可记得 ssh 允许我们 在远程联网的计算机上执行程序,并且在本地系统中看到执行结果——远端系统中产生的输出结果 被发送到本地系统中查看。我们可以利用。在本地系统中,我们执行 tar 命令,
这个 zip 程序既是压缩工具也是一个打包工具。这程序使用的文件格式Windows 用户比较熟悉, 因为它读取和写入.zip 文件。然而,在 Linux 中 gzip 是主要的压缩程序,而 bzip2 则位居第二。
在 zip 命令最基本的使用中,可以这样唤醒 zip 命令:
```
zip options zipfile file...
```
例如,制作一个 playground 的 zip 版本的文件包,这样做:
```
[me@linuxbox ~]$ zip -r playground.zip playground
```
除非我们包含-r 选项,要不然只有 playground 目录(没有任何它的内容)被存储。虽然会自动添加 .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%)
```
这些信息显示了添加到文件包中每个文件的状态。zip 命令会使用两种存储方法之一,来添加 文件到文件包中要不它会“store”没有压缩的文件正如这里所示或者它会“deflate”文件 执行压缩操作。在存储方法之后显示的数值表明了压缩量。因为我们的 playground 目录 只是包含空文件,没有对它的内容执行压缩操作。
使用 unzip 程序,来直接抽取一个 zip 文件的内容。
```
[me@linuxbox ~]$ cd foo
[me@linuxbox foo]$ unzip ../playground.zip
```
对于 zip 命令(与 tar 命令相反)要注意一点,就是如果指定了一个已经存在的文件包,其被更新 而不是被替代。这意味着会保留此文件包,但是会添加新文件,同时替换匹配的文件。可以列出 文件或者有选择地从一个 zip 文件包中抽取文件,只要给 unzip 命令指定文件名:
```
[me@linuxbox ~]$ unzip -l playground.zip playground/dir-87/file-Z
Archive: ../playground.zip
Length Date Time Name
0 10-05-08 09:25 playground/dir-87/file-Z
0 1 file
[me@linuxbox ~]$ cd foo
[me@linuxbox foo]$ unzip ./playground.zip playground/dir-87/file-Z
Archive: ../playground.zip
replace playground/dir-87/file-Z? [y]es, [n]o, [A]ll, [N]one,
[r]ename: y
extracting: playground/dir-87/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 命令把末尾的横杠解释为 “使用标准输入作为输入文件。”
这个 unzip 程序允许它的输出发送到标准输出,当指定了-p 选项之后:
```
[me@linuxbox ~]$ unzip -p ls-etc.zip | less
```
我们讨论了一些 zip/unzip 可以完成的基本操作。它们两个都有许多选项,其增加了 命令的灵活性虽然一些选项只针对于特定的平台。zip 和 unzip 命令的说明手册都相当不错, 并且包含了有用的实例。然而,这些程序的主要用途是为了和 Windows 系统交换文件, 而不是在 Linux 系统中执行压缩和打包操作tar 和 gzip 程序在 Linux 系统中更受欢迎。
### 同步文件和目录
维护系统备份的常见策略是保持一个或多个目录与另一个本地系统(通常是某种可移动的存储设备) 或者远端系统中的目录(或多个目录)同步。我们可能,例如有一个正在开发的网站的本地备份, 需要时不时的与远端网络服务器中的文件备份保持同步。在类似于 Unix 系统的世界里,能完成此任务且 备受人们喜爱的工具是 rsync。这个程序能同步本地与远端的目录通过使用 rsync 远端更新协议,此协议 允许 rsync 快速地检测两个目录的差异,执行最小量的复制来达到目录间的同步。比起其它种类的复制程序, 这就使 rsync 命令非常快速和高效。
rsync 被这样唤醒:
这里 source 和 destination 是下列选项之一:
* 一个本地文件或目录
* 一个远端文件或目录,以[user@]host:path 的形式存在
* 一个远端 rsync 服务器,由 rsync://[user@]host[:port]/path 指定
注意 source 和 destination 两者之一必须是本地文件。rsync 不支持远端到远端的复制
让我们试着对一些本地文件使用 rsync 命令。首先,清空我们的 foo 目录:
```
[me@linuxbox ~]$ rm -rf foo/*
```
下一步,我们将同步 playground 目录和它在 foo 目录中相对应的副本
```
[me@linuxbox ~]$ rsync -av playground foo
```
我们包括了-a 选项(递归和保护文件属性)和-v 选项(冗余输出), 来在 foo 目录中制作一个 playground 目录的镜像。当这个命令执行的时候, 我们将会看到一系列的文件和目录被复制。在最后,我们将看到一条像这样的总结信息:
```
sent 135759 bytes received 57870 bytes 387258.00 bytes/sec
total size is 3230 speedup is 0.02
```
说明复制的数量。如果我们再次运行这个命令,我们将会看到不同的结果:
```
[me@linuxbox ~]$ rsync -av playgound foo
building file list ... done
sent 22635 bytes received 20 bytes
total size is 3230 speedup is 0.14
45310.00 bytes/sec
```
注意到没有文件列表。这是因为 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 命令检测到更改,并且只是复制了更新的文件。作为一个实际的例子, 让我们考虑一个假想的外部硬盘,之前我们在 tar 命令中用到过的。如果我们再次把此 硬盘连接到我们的系统中,它被挂载到/media/BigDisk 目录下,我们可以执行一个有 用的系统备份了,首先在外部硬盘上创建一个目录,名为/backup然后使用 rsync 程序 从我们的系统中复制最重要的数据到此外部硬盘上:
```
[me@linuxbox ~]$ mkdir /media/BigDisk/backup
[me@linuxbox ~]$ sudo rsync -av --delete /etc /home /usr/local /media/BigDisk/backup
```
在这个例子里,我们把 /etc/home和 /usr/local 目录从我们的系统中复制到假想的存储设备中。 我们包含了--delete 这个选项,来删除可能在备份设备中已经存在但却不再存在于源设备中的文件, (这与我们第一次创建备份无关,但是会在随后的复制操作中有用途)。挂载外部驱动器,运行 rsync 命令,不断重复这个过程,是一个不错的(虽然不理想)方式来保存少量的系统备份文件。 当然,别名会对这个操作更有帮助些。我们将会创建一个别名,并把它添加到 .bashrc 文件中, 来提供这个特性:
```
alias backup='sudo rsync -av --delete /etc /home /usr/local /media/BigDisk/backup'
```
现在我们所做的事情就是连接外部驱动器,然后运行 backup 命令来完成工作。
#### 在网络间使用 rsync 命令
rsync 程序的真正好处之一是它可以被用来在网络间复制文件。毕竟rsync 中的“r”象征着“remote”。 远程复制可以通过两种方法完成。第一个方法要求另一个系统已经安装了 rsync 程序,还安装了 远程 shell 程序,比如 ssh。比方说我们本地网络中的一个系统有大量可用的硬盘空间我们想要 用远程系统来代替一个外部驱动器,来执行文件备份操作。假定远程系统中有一个名为/backup 的目录, 其用来存放我们传送的文件,我们这样做:
```
[me@linuxbox ~]$ sudo rsync -av --delete --rsh=ssh /etc /home /usr/local remote-sys:/backup
```
我们对命令做了两处修改,来方便网络间文件复制。首先,我们添加了--rsh=ssh 选项,其指示 rsync 使用 ssh 程序作为它的远程 shell。以这种方式我们就能够使用一个 ssh 加密通道,把数据 安全地传送到远程主机中。其次,通过在目标路径名前加上远端主机的名字(在这种情况下, 远端主机名为 remote-sys来指定远端主机。
rsync 可以被用来在网络间同步文件的第二种方式是通过使用 rsync 服务器。rsync 可以被配置为一个 守护进程监听即将到来的同步请求。这样做经常是为了允许一个远程系统的镜像。例如Red Hat 软件中心为它的 Fedora 发行版,维护着一个巨大的正在开发中的软件包的仓库。对于软件测试人员, 在发行周期的测试阶段,镜像这些软件集合是非常有帮助的。因为仓库中的这些文件会频繁地 (通常每天不止一次)改动,定期同步本地镜像,这是可取的,而不是大量地拷贝软件仓库。 这些软件库之一被维护在 Georgia Tech我们可以使用本地 rsync 程序和它们的 rsync 服务器来镜像它。
```
[me@linuxbox ~]$ mkdir fedora-devel
[me@linuxbox ~]$ rsync -av -delete rsync://rsync.gtlib.gatech.edu/fedora-linux-
core/development/i386/os fedora-devel
```
在这个例子里,我们使用了远端 rsync 服务器的 URI其由协议rsync://),远端主机名 rsync.gtlib.gatech.edu和软件仓库的路径名组成。
### 拓展阅读
* 在这里讨论的所有命令的手册文档都相当清楚明白,并且包含了有用的例子。另外, GNU 版本的 tar 命令有一个不错的在线文档。可以在下面链接处找到:
[`www.gnu.org/software/tar/manual/index.html`](http://www.gnu.org/software/tar/manual/index.html)