%ENV不起作用,我不能使用共享库

Dan*_*ele 10 oracle perl env dbi dbd

我不能%ENV在我的Perl脚本上使用var来使用Oracle库.

BEGIN {
    $ORACLE_HOME = "/usr/lib/oracle/10.2.0.3/client64";
    $LD_LIBRARY_PATH = "$ORACLE_HOME/lib";
    $ORACLE_SID="prod";
    $ENV{ORACLE_SID}=$ORACLE_SID;
    $ENV{ORACLE_HOME}= $ORACLE_HOME;
    $ENV{LD_LIBRARY_PATH}= $LD_LIBRARY_PATH;
};
Run Code Online (Sandbox Code Playgroud)

如果我打印$ENV{'ORACLE_HOME'},$ENV{'LD_LIBRARY_PATH'}一切似乎没问题但是,当我运行我的脚本时,我有错误:

install_driver(Oracle)失败:无法为模块DBD加载'/usr/local/lib64/perl5/auto/DBD/Oracle/Oracle.so':: Oracle:libclntsh.so.10.1:无法打开共享对象文件:否这样的文件或目录位于/usr/lib64/perl5/DynaLoader.pm第200行.(eval 3)第3行编译在(eval 3)第3行的require中失败.也许在预期的地方没有安装所需的共享库或dll在persistence.perl第22行

在网上搜索我发现在Perl上设置env变量的正确方法是使用%ENVhash.

导出ORACLE_HOMELD_LIBRARY_PATH通过unix shell(export LD_LIBRARY_PATH=...)它可以正常工作.有什么建议?

BRP*_*ock 10

LD_LIBRARY_PATH环境变量必须设置之前,你的程序开始-之前perl加载自身.更改它将BEGIN{}影响您启动的新程序,但它不会影响共享库的加载- 在这种情况下(虽然我从未使用过DBD :: Oracle)您正在将Oracle加载.so到已经运行的程序中程序,所以改变它的"为时已晚" LD_LIBRARY_PATH.动态链接器/lib/ld.so(或左右)之前就已启动perl,因此在编译和BEGIN{}运行脚本时,它已经设置好了.

可以尝试重新执行你的脚本作为它自己的继承者或者什么*,但是一个简短的shell脚本几乎肯定是最简单的解决方案:

  #!/bin/sh
  export LD_LIBRARY_PATH=/usr/lib/oracle/10.2.0.3/client64/lib
  export ORACLE_SID=prod
  exec /usr/local/bin/your-db-program "$@"
Run Code Online (Sandbox Code Playgroud)

* - 这有点疯狂,但是TIMTOWTDI:

  eval { 
     use DBD::Oracle foo bar baz; …
  };
  if ($@ =~ /install_driver\(Oracle\) failed/) {
     $ENV{LD_LIBRARY_PATH} .= ':/usr/lib/oracle/10.2.0.3/client64/lib';
     $ENV{ORACLE_SID} = 'prod';
     warn "Restarting with LD_LIBRARY_PATH reset:\n\n$@\n";
     exec { $0 } $0 => @ARGV;
  }
Run Code Online (Sandbox Code Playgroud)