Linux下通过crontab调度脚本时脚本所使用的环境变量问题


通过crontab调度脚本时脚本使用的环境变量与直接在shell中运行脚本时使用的环境变量不同(因为crontab并不知道你所使用的shell,只是简单的设置了HOME、LOGNAME、SHELL和有限的PATH等环境变量),因而可能导致“XXX command not find”的错误或者运行结果不一致的情况。


解决办法有四:
1.在脚本中设置环境变量,如,在cron_job.sh文件中:
#!/bin/bash
source $HOME/.bash_profile
some_other_cmd

当然也可以先把环境变量设置在一个单独的文件中如/path/to/my_env.sh
$ env | sort > /tmp/cmdLineEnv.out(注意使用运行脚本时所使用的用户执行命令)
然后在待运行的脚本中执行`cat /path/to/my_env.sh`
2.在脚本中使用绝对路径运行命令
可避免PATH环境变量导致的命令无法找到的问题,但不能避免其他环境变量造成的问题。

3.在crontab文件中设置调度脚本时使用的环境变量信息,如:
SHELL=/bin/bash
LANG=nb_NO.UTF-8
LC_ALL=nb_NO.UTF-8
PATH = /sbin
0 5 * * * sleep 5s && echo "yo"

使用此方法需注意:
在crontab文件的顶部设置
该特征仅对某些特定的cron的实现有效(如Ubuntu和Debin的vixie-cron、GNU mcron支持这一特性,而Archlinux和Redhat的cronie不支持这一特性)

4.在调度语句中设置环境变量,如:
0 5 * * * . $HOME/.profile; sleep 5s && echo "yo"

使用此方法需注意:
“.”表示source命令,不可忽略,当然,也可以直接以“source”命令替代“.”
真实情况下应将“$HOME”替换为实际的全路径
保存环境变量的文件可以是$HOME/.profile,还可能是$HOME/.bash_profile、/etc/profile等或者是自己特意创建的专门用来存放环境变量的文件。

也可以直接在调度语句中设置环境变量,如:
0 5 * * * SOME_ENV_VAR=some_value some_command some_parameters

或者写一个封装脚本封装设置环境变量的命令如cron-wrapper
#!/bin/bash
[ -r $HOME/.bashrc ] && . $HOME/.bashrc
[ -r $HOME/.profile ] && . $HOME/.profile
exec "$@"
然后在计划任务调度语句中
* * * * 1-5 ~/scripts/cron-wrapper ~/scripts/myscript.sh

参考
http://www-01.ibm.com/support/docview.wss?uid=isg3T1011623

相关内容