用Perl写了不少脚本, 例如收集数据的程序(gatherdata.pl), 需要在Crontab中进行任务设置, 这时就会发现原本在命令行下手工可以执行的Perl程序, 放到Crontab中就不能执行了, 原因是因为手工跑时, 已经设置了很多的环境变量, 而由Crontab启动程序时通常没有设置如下环境变量.

ORACLE_HOME=……
ORACLE_SID=……
LD_LIBRARY_PATH=$ORACLE_HOME/lib
NLS_LANG=.ZHS26GBK

    为解决这个问题, 常常会写一个Shell脚本来调用Perl脚本, 在Shell脚本中进行环境变量设置. 其实这个工作可以放到Perl脚本中, 省去编写Shell脚本这一步. 在数据收集脚本中, 通过命令行传入ORACLE_SID, 然后Perl脚本从特定目录的配置文件中, 得到与ORACLE_SID相对应的ORACLE_HOME (getOracleHome函数), 然后在Perl打开数据库连接前进行环境变量设置.

$ENV{“ORACLE_SID”} = $sid;
$ENV{“ORACLE_HOME”} = getOracleHome($sid);
$ENV{“LD_LIBRARY_PATH”} = getOracleHome($sid).”/lib”;
$ENV{“NLS_LANG”} = “.ZHS16GBK”;

    接下来就可以在Crontab中直接进行任务调度了.

1 1 * * * /home/oracle/admin/bin/gatherdata.pl -S test ……

    据说有公司的解决方法是将Oracle的客户端库文件(libclntsh.so)复制到系统库目录(/usr/lib), 但我个人不是很喜欢这种做法, 所以去想出这个方法.