I cannot use %ENV
var on my Perl script to use Oracle libs.
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;
};
If I print $ENV{'ORACLE_HOME'}
and $ENV{'LD_LIBRARY_PATH'}
all seems ok but, when I run my script I have the error:
install_driver(Oracle) failed: Can't load '/usr/local/lib64/perl5/auto/DBD/Oracle/Oracle.so' for module DBD::Oracle: libclntsh.so.10.1: cannot open shared object file: No such file or directory at /usr/lib64/perl5/DynaLoader.pm line 200. at (eval 3) line 3 Compilation failed in require at (eval 3) line 3. Perhaps a required shared library or dll isn't installed where expected at persistence.perl line 22
Searching on web I saw that the correct way to set env vars on Perl is to use %ENV
hash.
Exporting ORACLE_HOME
and LD_LIBRARY_PATH
through unix shell (export LD_LIBRARY_PATH=...
) it works correctly. Any advice?
One solution is to modify /etc/ld.so.conf
On CentOS/RHEL 6.4, you could create etc/ld.so.conf.d/oracle with this:
Obviously, modify as suits your ORACLE_HOME.
Then run
The
LD_LIBRARY_PATH
environment variable has to be set before your program starts — beforeperl
itself is loaded. Changing it inBEGIN{}
will affect new programs that you start, but it won't affect the loading of shared libraries — in this case (although I've never used the DBD::Oracle) you're loading an Oracle.so
into the already-running program, so it's “too late” to change theLD_LIBRARY_PATH
. The dynamic linker/lib/ld.so
(or so) is started beforeperl
, so by the time your script is compiled andBEGIN{}
runs, it's already set up.You could try to re-exec your script as its own successor or something*, but a short shell script is almost certainly going to be the simplest solution:
*- this would be kinda crazy, but TIMTOWTDI:
You could put the
export
commands into the start up script for your unix shell which you should have permission to edit. That way, the environment variables will be set whenever you start a new shell and all scripts and programs that use Oracle will pick them up.I wrote a few test scripts to verify that the environment is being set when you change
%ENV
:This prints out:
which is what I expected.
I then tried this:
and created a
test.sh
program that looks like this:In this case, my Perl script is running
test.sh
which prints out the value of the$FOO
environment variable that was set in my Perl script. Runningtest.pl
I get:This shows that not only is Perl setting the environment variables, but that it is also exporting those variables, so called shell scripts have access to them.
You can try a similar technique to verify that both
LD_LIBRARY_PATH
andORACLE_HOME
are being set before they're used. I suspect you'll find that this is indeed happening, but that your program still isn't working when you set%ENV
.This points to one conclusion: Setting the environment for
LD_LIBRARY_PATH
andORACLE_HOME
might be occurring too late by the time your Perl script starts. I believe the operating system examinesLD_LIBRARY_PATH
before Perl starts. I found this doing a search onLD_LIBRARY_PATH
:So,
LD_LIBRARY_PATH
is for theld.so
runtime shared library loader, Ifld.so
has already been loaded, changingLD_LIBRARY_PATH
won't do anything.I found a similar discussion on Perl Monks. I noticed someone found rerunning
env
seemed to work.I just went through something similar. I had to make sure that the Oracle environment was setup before anything else called it. Make sure the
BEGIN
block is before any other "use" statements. In my case, something was being called in Apache's httpd.conf file, so I had to setup my environment there instead of in my package.