分类:
2008-03-19 16:44:58
移动和管理存储在多个系统中的文件
了解几种用来在不同系统之间移动文件、以及实现远程数据同步的技术。
近些年来,计算机硬件变得非常的便宜。每 GB 的硬盘空间只需要 0.50 美元,一台 19 英寸的平板显示器售价还不到 200 美元,一台可以运行 UNIX 的便携式电脑售价还不到 1000 美元。即使是专门的服务器硬件也不是很昂贵。
价格如此的便宜,使得一个中型或大型的组织可以为不同的任务采用单独的硬件设备。而且,只需要将计算机连接到网络、将磁盘映像复制到一台普通的计算机并重新启动,就可以轻松地扩展计算能力。当然,没有免费的午餐。每台计算机都需要电能、空调以及关心和爱护。
在管理大量的计算机时最常见的问题之一是,如何保持这些系统最新和一致。在有些情况下,您希望在所有的地方都部署某个应用程序的相同版本,以免不一致的特性让用户感到困惑。或者,作为另一个示例,您可能希望在用于相同目的的不同服务器中安装相同的操作系统。具有可预测性是很有好处的。
即使您只拥有一台便携式计算机和一台台式计算机,保持这两台计算机之间的同步也可能是一项艰巨的任务。今天,您正在使用便携式计算机进行工作。而昨天,您可能使用台式计算机对某些内容进行了修改。您可能在这两天中都向中央文件服务器上传或从中下载了一些文件。随着数据的上传和下载,很快您就会被什么数据放在什么地方给弄糊涂。
在本系列的第 5 部分中,让我们来讨论一些有价值的技术,它们可以帮助您控制文件数目急剧增加的局面。
压缩和转发
很显然,要在多台不同的计算机之间维护数据的一致性,最简单的方法是随身携带您的文件(电子表格、数据库、文本文件,等等)。如果您可以直接接触到所使用的每台计算机,那么您可以携带一个便携式磁盘、CD-RW 或大容量的便携闪存,并在需要使用这些文件时插入存储设备。
然而,如果您所使用的计算机是远程的或无法直接接触到的,假设在爱达荷州 Boise 的机房中,无法直接连接外部设备。相反,您可以为您的(一些或所有的)文件建立存档,连接到局域网 (LAN) 或广域网 (WAN) 中,将存档复制到目标,然后恢复这些文件以便继续工作(而且,您可以使用存档作为简单的备份,以便在出现灾难的情况下保护您的文件,比如将计算机忘在出租车中)。
在 UNIX 系统中,可靠的实用程序 tar 可以用来简化构建存档的工作。tar 实用程序将一个或多个文件和目录打包为单个文件,并保持原始文件的大小、拥有者、权限、文件类型及其在文件系统层次结构中的位置。tar 实用程序将您的文件完整地记录到磁带中,tar 是磁带存档程序 (tape archiver) 的首字母缩写。
例如,假设您在一个目录中放入了各种各样的文件,如清单 1 所示。
清单 1. 文件目录
$ cd stuff
$ ls -lR
.:
drwxr-xr-x 2 mstreicher mstreicher 4096 Oct 12 19:11 css
-rwxr-xr-x 1 mstreicher mstreicher 91 Aug 17 2005 demo.rb
-rw-r--r-- 1 mstreicher mstreicher 111563 Oct 12 19:10 tech.pdf
./css:
total 16
-rw-r--r-- 1 mstreicher mstreicher 711 Mar 25 2006 style.css
-rw-r--r-- 1 mstreicher mstreicher 11353 Apr 10 2006 valid.css
要为这两个文件和一个目录创建存档,可以运行下面的 tar 命令:
$ tar --create --verbose --gzip --file archive.tgz *
css/
css/style.css
css/valid.css
demo.rb
tech.pdf
--create 选项告诉 tar 创建一个存档;--verbose 选项为 tar 所处理的文件生成一个列表;--gzip 选项启用 gzip 方式的压缩,这将缩小该存档的大小;而 --file archive.tgz 指定了存档的名称。
Shell 将星号 (*) 解释为“任何文件”,所以对其展开后为两个文件和一个目录。从上面的输出中您可以看出,tar 对 css 目录进行了存档,同时递归地对该目录中的内容进行了存档。
在运行 tar 命令之后,当前目录中包含了一个新的文件 archive.tgz:
$ ls -l archive.tgz
-rw-r--r-- 1 mstreicher mstreicher 105470 Oct 13 17:16 archive.tgz
现在,您可以将 archive.tgz 复制到另一台计算机,并在远程计算机上使用 tar 解压存档的内容。事实上,用来恢复文件的命令行与前面使用的命令行基本相同。要对这个存档进行解压,可以使用:
$ tar --extract --verbose --gunzip --preserve-permissions --file archive.tgz
这个 tar 命令将解压 archive.tgz 压缩文件中的内容。--extract 选项与 --create 选项正好相反;--gunzip 与 --gzip 相反,而 --preserve-permissions 将重新创建原始文件的权限。
在运行了这个命令之后,完整地恢复了所保存的文件,并保持了原来的时间戳、权限和文件名。同时,重新创建了名为 css 的目录,并将其中的内容压缩到了最初的位置。
tar 实用程序具有许多选项:--create、--extract 和 --list(列出 .tar 文件的内容而不展开该文件)。其他的选项(如 --gzip 和 --preserve-permissions)用来控制 tar 如何创建存档。有关在您的 UNIX 版本中每个选项更详细的信息和正确的语法,请参阅 tar 的 man 页面。
创建存档、将其复制到目标、然后再解压缩,这种方法非常有用,但是可能比较费事。另外,如果存档非常大,您可能无法同时存储存档和解压后的文件。如果源和目标计算机之间通过 LAN 或 WAN 连接,那么为了节省时间,您可以组合使用 Secure Shell (SSH) 和 tar 命令,以将文件存档、复制和解压合并为一步操作。下面是完成这项工作的命令:
$ (cd ~/stuff; tar --create --gzip --file - *) | \
ssh destination tar --extract --gunzip --file --verbose -C stuff
该命令进行了很多操作,所以让我们对其进行分解:
命令中带圆括号的部分称为subshell。subshell 中进行的更改,例如更改目录,不会影响到您的命令行,但是它将影响 subshell 的执行环境。因此,第一个短语 (cd ~/stuff; tar --create --gzip --file - *) 更改到目录 ~/stuff,然后运行 tar。因为 subshell 后面跟着管道,所以 subshell 的所有输出都通过管道传输给了下一个命令。
与许多其他的 UNIX 实用程序一样,tar 可以分别向标准输出 (stdout) 写入、从标准输入 (stdin) 读取。stdout 和 stdin 通常表示为连字符 (-)。所以,短语 --create --file - 在 stdout 上创建存档。
管道 (|) 将 subshell 的所有输出通过管道传输给 ssh。这样可以有效地将所有的输出从源计算机传输到目标计算机。
最后,目标计算机运行自己的 tar 实例对存档进行解压。然而,这里的 --extract --file - 从标准输入 读取存档。-C 选项强迫接收方 的 tar 在开始进行任何处理之前,将目录更改到 stuff(在远程 home 目录中)。最后的结果是,将通过 ssh 传输的存档解压到 ~/stuff 中。
通过这一个(有些冗长的)命令,您创建了、传输并解压缩了存档。顺便提一下,对该命令行中内容的顺序稍作颠倒,您就可以从远程计算机中获取创建的存档并解压到本地计算机。下面的命令可以实现这项任务,在本地计算机中运行:
$ ssh destination cat archive.tgz | \
(cd ~/stuff; tar --extract --gunzip --file -)
在远程计算机上打开远程存档,将 cat 产生的字节流发送到 subshell,这个 subshell 首先更改目录,然后对存档进行解压缩。(为 tar 命令添加 -C ~/stuff 可以起到与前面相同的作用;这个示例显示了 subshell 也可以使用输入。)
您可以使用相同的方法在同一台计算机上对文件进行镜像。尝试下面的命令:
tar --create --file - * | tar -C /path/to/directory --extract --file -
通过复制方式存档
tar 实用程序加上 ssh,可以很方便地将文件从一台计算机传输到另一台计算机。tar 实用程序创建存档,而 ssh 则实现该存档的安全传输。
另一种方法是使用 SSH 固有的能力将文件从一台计算机传输到另一台计算机。sftp 是 SSH 的另一种特征,它提供了文件传输协议 (FTP) 的所有特性,并且在传输的过程中对文件数据进行保护。(通常,不建议使用 FTP,因为它不是很安全,然而公共的 FTP 站点是个例外。)
如果您曾经使用过 FTP,sftp 实际上与其相同。只需输入 sftp destination 以连接到名为 destination 的远程计算机,然后运行 FTP 命令,如 cd、lcd、mput 和 mget 以便对文件进行双向移动。
在两台计算机之间传输文件的另一种方法是使用 scp,即安全复制 (secure copy)。顾名思义,scp 的工作方式与普通的 cp 非常相似,它可以用来将文件从一个地方复制到另一个地方,可以在同一台计算机上或两台不同的计算机之间。
例如,如果您希望在本地计算机中将一些文件和目录复制到另一个目录,您可以运行与清单 2 中所示类似的代码。
清单 2. 在两台计算机之间复制文件
$ ls -lF
drwxr-xr-x 2 mstreicher mstreicher 4096 Oct 12 19:11 css/
-rwxr-xr-x 1 mstreicher mstreicher 91 Aug 17 2005 demo.rb*
-rw-r--r-- 1 mstreicher mstreicher 111563 Oct 12 19:10 tech.pdf
$ cp -pr * /home/joe/stuff
$ ls -lF /home/joe/stuff
drwxr-xr-x 2 mstreicher mstreicher 4096 Oct 12 19:11 css/
-rwxr-xr-x 1 mstreicher mstreicher 91 Aug 17 2005 demo.rb*
-rw-r--r-- 1 mstreicher mstreicher 111563 Oct 12 19:10 tech.pdf
在这个示例中,cp -pr 递归地将所有的文件和目录复制到 /home/joe/stuff。-r 表示递归;-p 表示保持该文件的时间戳。
您可以使用 scp 完成相同的工作(即在本地进行复制):
$ scp -pr * /home/joe/stuff
但如果您指定了远程系统,那么 scp 可以通过网络复制文件:
$ scp -pr * destination:/home/joe/stuff
假定目标计算机中存在 /home/joe/stuff 目录,并且对您来说是可写的,那么这两个文件和一个目录将完整地复制到远程计算机。与 cp 一样,scp 使用 -p 表示保持文件的时间戳,-r 表示递归。
scp 很容易使用,特别是当建立了私-公钥对时,可以避免在每次执行 ssh/scp/sftp 操作时输入密码。
然而对于 scp,有一个特殊的问题需要注意。假定您在自己的 home 目录中有一个名为 doc 的目录,并且您希望将其复制到远程系统。而且,您希望当文件或目录具有相同名称时,使用 ~/doc 中的内容替换远程 doc 目录中的内容。需要使用的命令应该与下面所示类似:
$ scp -pr ~/doc destination:/path/to/doc
请注意,目标计算机上的目录没有尾部的斜杠 (/)。scp 将这个路径解释为“将 ~/doc 目录中的内容复制到目标计算机的 /path/to/doc 目录”。与 cp 一样,与本地文件和目录具有相同名称的远程文件和目录将被覆盖,而远程系统中所特有的文件将保持不变。
然而,如果您添加上尾部的斜杠,如下所示:
$ scp -pr ~/doc destination:/path/to/doc/
scp 将后面的这个路径解释为“将 ~/doc 目录复制到 /path/to/doc/ 目录”。所以,将本地 doc 目录复制到远程目录中,而不是覆盖远程目录的内容。
尾部的斜杠并不是一个错误。有时您可能希望使用它,而有时您可能不希望使用它,这取决于实际情况。
保持同步
scp 非常有用,因为它与 cp 非常接近。tar 和 ssh 稍微复杂一点,但它们可以保持文件的元数据,如拥有者和权限。
但是 tar 和 scp 都无法对本地和远程目录中的内容进行同步。例如,如果您在本地系统中更改了一个文件,并在远程系统中更改了另一个文件,那么为了建立工作镜像,您不得不运行两次 scp 命令。现在可以想象一下,如果您更改了大量的文件,并且其中许多具有相同的名称,很快地,您将会发现同步工作变得非常复杂。
幸运的是,有一个名为 rsync 的神奇的实用程序,它可以对文件集进行同步。然而更有价值的是,rsync 仅对那些更改过的数据进行传输,这样可以使得传输的数据量最小化。
与 tar 一样,您可以将 rsync 与 ssh 组合使用,以连接到远程系统并对本地和远程的文件集合进行同步。与 scp 一样,您可以使用 rsync 在本地进行文件复制。您还可以使用 rsync 列举文件。
其最大的优点在于,rsync 具有各种选项,要使得一个目录成为另一个目录真正的镜像,可以使用相应的选项删除原始目录中不存在的那些文件。让我们来看一些示例:
$ rsync -e ssh --times *.txt destination:
这个命令将当前工作目录中所有的文本文件复制到您在名为 destination 的计算机上的 home 目录中。-times 选项保持每个文件的访问权限、创建和最后修改时间。
$ rsync -e ssh --times --perms --recursive --delete doc destination:
这个变化的 rsync 命令在目标计算机上您的 home 目录中创建本地 doc 目录的镜像。同时保持文件的时间和权限,并且删除外来的文件(即,在本地目录中不存在的远程目录中的文件)。
因为 rsync 可能执行一些重要的更改,所以您可能希望为该命令行添加 --dry-run 选项,以便预览 rsync 计划完成哪些操作。--dry-run 并不进行任何更改,它仅仅显示将要执行的操作,如下面的清单 3 所示。
清单 3. 预览 rsync 将要执行的操作
$ rsync -e ssh --dry-run --times --perms --recursive --delete bin destination:
building file list ... done
bin/
skipping non-regular file "bin/HTML.pl"
skipping non-regular file "bin/Quark.pl"
bin/Responses/
bin/Responses/DBI.pm
bin/Responses/Response.pm
skipping non-regular file "bin/XML.pl"
bin/backupdca.sh
bin/lib/
bin/report.pl
bin/report.txt
sent 724 bytes received 108 bytes 554.67 bytes/sec
total size is 168879 speedup is 202.98
rsync 具有许多选项:
-a 是非常有用的选项,因为它是 --group --owner --perms --times --devices --links --recursive 的缩写。--devices 重新创建设备文件,而 --links 将符号链接复制为符号链接,而不是复制符号链接所指向的内容。
--update 可以防止 rsync 覆盖较新的文件。如果远程系统具有比本地系统较新的文件,那么将会保留远程系统中的这个文件。
可以尝试使用 --verbose 选项,以便在 rsync 命令执行的过程中进行观察。
同样的,有关 rsync 的更多使用技巧,请阅读 man 页面。它具有一种重要的特性,即您可以定义需要包括和排除的文件。
数据无处不在
UNIX 已在网络环境中使用了 20 多年。其间,硬件发生了很大的变化,而大部分软件则保持不变,这为用户和系统管理员带来了困难。最大的问题之一是,随着磁盘的容量变得越来越大,要想跟踪所有的数据更加困难。这些实用程序,如 tar、sftp/scp 和 rsync 可以用来完成各种磁盘操作。