title | date |
---|---|
57期 - 决胜命令行 |
2012-09-22 13:33 |
#使用SSH和Rsync
Lucas Westermann 著 翻译:黄傲妮 校对:Kitty 顾履冰
早在37期,我就写了一篇关于如何在你自己的电脑上配置一个SSH服务器的文章,目的是为了能够将SSH用作SOCKS代理。因为我觉得不是每个人都想那样去用它,所以决定把重点放在第二个我常用的命令上(第一个我最常使用的命令是“pacman”— ArchLinux的包管理解决方案)。在告诉你这个命令是什么玩意儿之前,我会先简要解释一下为什么你将会对此方案感兴趣。明确地说,它可以让你在局域网中同步两台电脑上的目录和文件(而且,如果配置正确的话,也可以在互联网中实现)。我使用它是为了同步我的笔记本和PC上的音乐、持续更新我的配置文件,而且还能随我需要将任何东西从一台设备拷贝到另一台上。这儿有几个命令供你选择,其中两个就是scp(安全拷贝)和rsync。本文,我们将重点关注rsync,因为它提供了进度信息、更新特性,以及有用的开关,比如--ignore-existing。
你可能会问我为什么不使用Dropbox、硬盘,或者U盘(针对较小的文件)?答案很简单:Dropbox提供的空间数量有限,而其他两者需要我定期做备份。如果在你的“发送端”(此例中,我的PC是发送端)上已经配置好SSH,而在“接收端”(我的笔记本)上有一个SSH客户端(没有服务器请求),然后你就可以写一个简单的脚本去运行cron例程了(也就是说,通常不需要再有任何输入了)。如果想自动化运行这些东西,你就需要用密钥代替密码来配置你的SSH,如此一来就不需要任何的输入即可访问你的服务器。这个非常简单(用ssh-keygen去创建这个密钥,然后将公共密钥复制到服务器上),更多详情见本文后的链接。
一旦你配置了SSH,就该考虑一下这个脚本应如何运行了。我没办法提供一个示例脚本,因为我还没有执行过一个像样点的脚本。在设计脚本的时候,你应该考虑一些东西,比如: 这个脚本应该只用于你使用家庭网络的时猴(通过检查无线网络的ESSID,如果在家里你通过连接线将你的本本链接到局域网,请检查eth0是否被处于激活状态,或者仅仅考虑在某个特定时间运行此脚本)。这样做的原因是,除了你的家庭网络,在某一位置时可能会有很多失败的SSH链接。不过还是按照你自己的喜好,寻找一种适合自己的解决方案吧。最后把它写进这个脚本的if语句中。
你想同步多少文件/目录,哪一个才是你想要的呢?你要么硬编码每个文件或目录到这个脚本中,要么在你机器上创建一个基于文本列表的位置存储信息,然后用一个while语句和readline去处理文本行。我推荐几个文件:.bashrc(或者用shell的rc文件)、.Xdefaults(可配置终端颜色)、音乐、图片,以及窗口管理的各种配置文件(XMonad、DWM等等。)。
你需要更新(即需要保留最新的文件备份),或者忽略在接收端已经存在的文件(对于音乐文件和图片来说很有用)吗?你需要递归查找文件(在一颗目录树下)吗?rsync提供了一些其他有用的选项(见本文第二部分)。
目标文件夹和资源文件夹在同一个地方吗?如果没有,你就应该记录每个文件的去向(同第二部分)。
空间——在接收端上有足够的空间放置你所有来自发送端的文件吗?如果没有,你要怎么办?要么减少你所同步的文件清单内容,要么在脚本增加一个检查点,用df -h设置一个限制范围(也就是说如果只剩余9GB,则停止同步,同时发邮件或者给与你提示)。
如果你已经考虑到了这些点,那么就该写脚本了。我建议在你的脚本中至少要有两项检查(网络连接是否正确,以及发件人当前是否在线)。脚本剩余部分完全由你决定,包括什么时候以及怎样运行它。想想在24期中,我写的那篇关于cron的文章,在那时我已经列举了大量例子,因此在这里我只简单说一下可供你使用的选择。配置cron任务时,你可以将脚本转储在/etc/cron.hourly,或者/etc/cron.daily下。另一种选择是编辑你的crontab(crontab -e )。在crontab中你可以创建一行例程,让脚本在设置的小时/日期运行,或者设置它在某个特定的时间(也可以使某个特定的日期)运行等等。我觉得每天运行一次就已经足够了。
##rsync
正如你从上述3点所看到的,rsync为避免复制过多的文件而提供了大量检查。以下是一些有用的命令参数:
-u (--update): 跳过接收端上较新的文件
--inplace: 原位更新文件
--append: 在较短的文件末添加数据
-x: 避免越过文件系统界限(即坚持一个分区)
--existing: 不在接收端上创建一个新的文件,仅仅更新已存在的文件
--ignore-existing: 忽略接收端已存在的文件
--max-size=SIZE: 不复制任何比此文件大的文件(--min-size 也存在,尽管在这种情况下用处不大)
--exclude=PATTERN: 排除与此模式匹配的所有文件
--exclude-from=FILE: 从文件读取模式
--partial: 保留部分复制的文件
rsync其他一些有用的开关参数:
--delay-updates: 将更新的文件放在最后
-r (--recursive): 依随目录树
-d: 非递归复制目录(默认情况下rsync根本不进入任何目录)
-l (--links): 复制符号连接作为符号连接
-E (--executability): 保持文件的可执行性(对脚本有用)
-h: 大小和输出的可读性
--progress: 每个文件都显示进度条
欲得完整的列表,请查看rsync的帮助手册。
rsync命令的基本格式是:
rsync <switches> <source> <destination>
因此,如果我想更新PC机上~/scripts到笔记本上~/.bin里所有文件的话,我会写:
rsync -ru [email protected]:/home/lswest/scripts ~/.bin
这样就会将它复制过来了。从逻辑上讲,你将需要用PC机的真实IP代替本地主机的IP,但这仅仅是一个例子。
为了圆满结束这篇文章,我想做几点syncing之外的提醒:在互联网上同步,虽然有用,但是应该保持一个最低限度,这仅仅是因为控制网络流量;虽然加密,但是流量将会相当庞大,还可能惊动网管,又或者你可能会碰到一些数据的限制。再者,ssh密钥比密码更安全,所以无论如何我强烈推荐你使用它们。
如果大家对真实的样例脚本有大量需求,我会很乐意在下个月发布。然而,我还是建议你尝试写自己的,或者定制任何适合你需求的例子脚本。如果你确实想要一个示例脚本,请发邮件让我知道(地址在下方)。如果你自己的脚本有具体问题,也可以发邮件给我。
任何人有问题、忧虑,或者仅仅想分享已经实现的脚本,我的邮箱全天候等待[email protected]。如果你发邮件给我,记得在标题中包含C&C和FCM,以便于我不会忽视它。
链接:https://wiki.archlinux.org/index.php/SSH_Keys#Generating_an_SSH_key_pair>