在Ubuntu中用cron实现代码自动编译


公司新项目组组建,开发和测试环境重新构建,勉为其难的客串了一下配置管理员,前后配置了cvs服务器,nfs服务器,samba服务器,自动备份,自动清理,自动编译等等,等等。总体来说,配置不会很难,但要将所有的结合起来,实现一些协同工作,还是有些麻烦的。

工作应用和自己装着玩,完全是两码事,一旦用起来,很多奇怪的问题就像水中的葫芦,你摁下这个,那个就浮了起来,有时候真有崩溃的感觉。作为开发,自动测试是很重要的,而其前提条件就是,要实现自动编译,自动备份。开始写了一个脚本,单独执行好好的,但是一加入cron,就没有任何反应了。

经过查证才发现,cron工作环境是跟用户脱离的,简单点说,就是当前用户定义的环境变量,对于cron是无效的。这种没有输出的查错,是有些技巧的。关键在于,重定向的灵活运用。最简单的方法是将错误输出定向到文件中,方便看错误类型。

对于自动编译来说,首先就是要自动checkout源代码,但是,cvs checkout是会引用当前用户的环境变量的,而cron是一个清洁的环境,所以要将平时不用的东西加进去。

那么现在的问题是:如何在cron中实现cvs login呢?毕竟里面没有交互方式。实现有两种方式,先说难的:

1.众所周知,/bin/bash是不支持非交互方式输入密码的(这种说法不准确,姑且这么说吧),也就是你不能期望用这种方式输入密码:

cvs login

但有种shell是支持的,大概叫做expect,用spawn方式是可以的。因为我不打算用,所以就不详细说了,这个也有一大堆的。

2.呵呵,另外种方式很无厘头,我是没有认真看cvs手册的,不知道众位兄弟认真看没有。不知道我所应用的这条指令,里面有没有这么详细的说明,反正我是不想再查了。找遍全世界,才看到一个人提到这个,还不是针对我这个问题的。

cvs -d:pserver:username:password@cvsserverip:/cvsroot co -d $DIRBAK $DIRSOURCE 2>>$ERRORFILE >$TMPRECFILE;

这样cvs登录时所需要的环境变量,用户名和密码全有了。就不用担心别的了。至于$DIRBAK $DIRSOURCE 2>>$ERRORFILE >$TMPRECFILE这几个变量,前两个我想都知道是怎么回事了,后面两个随后解释。

问题似乎都解决了。然而,共产主义道路是曲折的。脚本是自动运行起来了,松了一口气,但检查发现,代码取出来是不全的。怎么回事呢?丈二和尚摸不着头脑。

这种东西查错是需要经验的,根本不可能期望网上能找到答案。猜测是cron不支持某种行为,给cvs checkout指令发了一个信号,让cvs终止运行了。

但怎么去查证这个信号呢?开始我用trap指令,放在脚本去捕捉,结果效果不好,还误导了我。后来用了一个比较简单,让人崩溃的方法。

大家都知道,标准出错的文件号是2,那么将2重定向一下不就ok了吗?最后的方法总是最好的,终于发现,原来cvs遭遇到一个SIGPIPE信号,难怪会终止了。

按我的猜测,cron派生了cvs之后,因为是后台程序,没有终端,自然标准出错,标准输出都没有了,重新定向到管道了。而cvs checkout会向标准输出和标准出错输出大量信息,这样,有写没有读,自然会管道破裂了。

知道原因了,解决就方便了,用2>>$ERRORFILE >$TMPRECFILE将标准出错,标准输出分别定向到$ERRORFILE和$TMPRECFILE中,重新执行,果然一切ok。

相关内容