SHELL TIPS: rsync 和 crontab 变量

本周我遭遇了一个惨痛事件,远程开发机有两块硬盘同时损坏,整个分区数据完全丢失。这直接导致我在开发机上 home 目录中所有文件人间蒸发了,真是一觉回到解放前!

值得庆幸的是这件事发生在端午假期中间,放假前我把大部分源代码都提交到了库里,辛苦劳动的损失倒不大。但是之前种种努力搭建的开发环境全丢失了,这一点让人很郁闷。为了不再遭受这样的损失,我痛下决心学习了一下 rsync,用来同步和备份数据。

不得不说 rsync 也是一个神器啊,man rsync 发现有各种灵活用法,最有用的我觉得还是通过 ssh 来备份的方法。发现了这个秘密后,我觉得用来备份自己的网站数据也不错。下面是我使用的参数:

rsync -avzuptS --delete --max-delete=100 -e "ssh" username@solrex.org:~/ ~/backup

如果懒得输入 ssh 密码,可以使用 ssh 公钥认证

一旦配置了公钥认证,这个备份命令就可以定制为 cron 任务定时执行了。这时候我发现一个有趣的问题:如果镜像了整个 home 目录的话,无法记录命令执行日志。 因为无论日志写入到 home 目录下哪个地方,都会因为远端没有这个文件被 rsync 删除掉。无奈之下只好使用笨方法,让 cron 把同步日志发邮件给自己。

$ crontab -l
SHELL=/bin/bash
HOME=/home/work
MAILTO="someone@somesite.com"
PATH=/home/work/local/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin
00 21 * * * mirror_site

把 SHELL 配成 /bin/bash 的原因是 /bin/sh 可能会导致一些不常见的诡异问题,例如这个。同样,在 crontab 中声明 PATH 环境变量可以避免某些命令找不到的问题,特别是自己写的放在 home 目录的脚本。

用 Linux 命令行工具自动追踪车票信息

前一篇博客中说到我买票失败的经历,也充分表达了我想买一张二手座票的意愿。怎么办呢?只好到网上各二手火车票信息平台去找了。心肠不好的人肯定幸灾了祸地在想:“哈哈,这个倒霉的小伙儿该对着浏览器不停地按 F5 了!” 你才 F5 呢,你们全家都 F5。那是典型的 Windows 用户的想法,不要以为 Linux User 跟你一样傻。

前面都是玩笑话 :),本文只是想介绍一下在 Linux 下有什么更方便的方法来追踪网页发布的信息,以展示 Linux 的命令行工具有多强大(也响应一下 Eric 师兄的文章:完全用键盘工作-3:常用的命令行工具)。

我们就拿火车网为例,通常情况下 Windows 用户为了在火车网上找一张二手火车票信息,会不断地到查询页面刷新,看有没有自己需要的车票。而一个 Linux 用户的做法会有何不同呢?一般来讲他会用工具来做这件事情,而不是在那傻刷,浪费时间。

怎么做呢?有很多种方法,我这里来介绍一种比较好玩的方法,用脚本自动跟踪信息,如果有结果就发送一个 Gtalk 消息给自己。

首先,写一个命令行发送 Gtalk 消息的 Python 脚本。其实我本打算用 freetalk 来做这件事的,奈何咱学识浅薄,不懂 freetalk 脚本该怎么写,也不知道 scheme 语言为何物。没办法,只好用 Python 来做了。下面内容就是用 Python 发送 gtalk 消息的脚本(需要 Linux 上装有 python-xmpp):

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# Usage: gtsent.py "SOMEBODY@gmail.com" "Message"

import xmpp
import sys

login = 'USERNAME' # without @gmail.com
pwd   = 'PASSWORD'

cnx = xmpp.Client('gmail.com', debug=[])
cnx.connect( server=('talk.google.com', 5223) )
cnx.auth(login, pwd, 'python')

cnx.send(xmpp.Message(sys.argv[1], sys.argv[2]))

将以上内容保存为 gtsend.py 文件,chmod u+x gtsend.py,修改 USERNAME 和 PASSWORD 为你的另一个非[常用] gmail 帐户名和密码。这样执行 ./gtsend.py SOMEBODY@gmail.com "Message" 就可以给 SOMEBODY@gmail.com 发送消息了(当然了,前提是 SOMEBODY@gmail.com 好友列表中有 USERNAME@gmail.com,请注意这里大写只是为了方便阅读)。

其次,写一个 Shell 脚本,用来追踪网页,过滤信息并发送 gtalk 消息。这个就更简单了,使用火车网提供的查询表单接口,用 wget 抓下来,再 grep 一下即可,bash 脚本如下:

#!/bin/bash
URL="http://www.huoche.com.cn/piao/2piaoserach.asp?ICheci=T65&type=0"
RESULT=`wget -O - $URL | iconv -f gbk -t utf8 | grep -i -e "t65.*南京.*硬座\
.*2008-9-28"`
if [ $(echo $RESULT | wc -c) -ge 5 ]
then
  /home/solrex/gtsend.py "YOURSELF@gmail.com" "$RESULT $URL"
fi

将该脚本保存为 get_tickt.sh,chmod u+x get_tickt.sh。这个脚本的工作流程是:wget 以 GET 方式提交对 T65 转让车票的查询,得到的结果输出到标准输出,然后将 GBK 编码转换为 UTF8 编码,再 grep 看是否含有“T65 南京 硬座 2008-9-28“关键词。如果有的话,用 gtsend.py 发送一个提醒消息给自己 gtalk 帐户;如果没有结果,什么都不做。

最后,将上面脚本加入 cron 列表每 10 分钟定时执行一次。 执行 crontab -e,添加下面一行即可(注意需要修改到该脚本的路径):

*/10 * * * * /home/solrex/get_ticket.sh

然后呢,你就可以高枕无忧,开着 Gtalk 等消息吧。当然,不一定能等得到 :(,唉,对我们来说, No news is BAD news!

当然,根据不同情况,你可以把追踪的信息换成别的东西。比如追女孩子的时候,可以用上面方法来实时跟踪她的最新博客,实时跟踪她在 BBS 上的留言,永远保持自己沙发的地位,说不定人家就感受到了你的关心,然后...具体方法我就不教了哈...