2012年6月7日星期四

Crontab 碰到的一些问题(环境变量,cmd)

    之前在一台机器上配置得好好的,昨天换了一台机器,然后配置的时候怎么都不行,郁闷。现象:配置后crontab后,程序没有运行。
    尝试解决之:首先是怀疑crontab的服务没有启动,因为没有root权限,不能用命令看crontab状态,问同事,同事说crontab是默认启动的,然后我ps -ef|grep cron一把,发现cron是在跑的。这就不懂了,因为程序里面是有写log的,但是log文件可以看出来程序一直没跑。再问同事,然后他加了一条cmd在crontab里面:echo "1" 1>/home/temp.log,过了一会这个log文件就有内容了,可以看出来cron服务是正常运行的。这就怪了,我的程序是一个很简单的程序啊,怎么就跑不起来。当时同事说一般这种问题都是环境变量引起的。我的程序是使用了mysql库,但是我在shell里面直接运行都可以,应该不存在环境变量的问题吧。(就是这个想法导致我后来绕了一个大弯)。
    到这个时候,我开始怀疑是不是在cron里面程序的标准输出被重定向了啊,其实程序是运行了的呢(这里我没有先想办法确定程序是否运行)。所以我就写了个简单的测试程序,就是main函数里面只有一个printf("test"),然后在crontab里面配置cmd为:/home/test 1>/home/test.log,稍等了一下,log文件马上就有内容了,这下看来是程序有问题了。我把自己的程序main函数改成只有一个打印语句,居然还是不行,怒了。难道是编译的时候有的库有问题(这里我已经走远了。。),为了证实这个,我改makefile,一个个库来编译(当时都居然没想到二分法!),最后终于发现是只要编译了mysqlclient库就有问题(我已经走远到天涯海角了),然后上网google之,还是没发现类似的问题啊。
    百思不得其解,然后突然想到看别人的crontab配置里面有这样一句:2>&1,意思就是说标准错误信息和标准输出一样可以被重定向到一个文件,也许这个可以让我看看有没有出错信息呢。加上,马上发现程序运行时提示找不到mysql库,这下我终于想到是环境变量的问题了。由于我没有root权限,不能直接在/etc/crontab里面加上环境变量。所以就要写一个运行脚本,在脚本里面export LD_LIBRARY_PATH=/data/lib,然后在脚本里面调用程序。cron配置的时候就运行这个脚本就可以了。
    修改完,过一会居然还有错,提示找不到程序文件。嗯,我在脚本里面调用程序用的是"./"这个相对路径来调用程序,但是crontab里面用的是用绝对路径来找运行脚本,比如:/home/auto_run.sh,这样就导致找不到程序文件了。修改成:cd /home;./auto_run.sh,有cd /home这句命令后,就可以改变当前目录,然后可以找到程序文件了。这下终于可以了。
    回想这个问题,还真是绕了不少弯啊,主要是没有利用1>/home/temp.log 2>&1这种来查看输出。因为cron是一个守护进程,它设计成为捕捉所有的stdout和stderr然后mail给用户(这个没看cron的源代码,估计也是这样),所以在crontab里面只配置echo是不行的,必须把stdout重定向到文件,这样就可以了。

没有评论:

发表评论