Discussion:
How to set LD_LIBRARY_PATH
(too old to reply)
newbie01 perl
2010-05-28 07:45:14 UTC
Permalink
Hi all,

Can someone advise how to set LD_LIBRARY_PATH from within the Perl scripts?

If I set LD_LIBRARY_PATH from the command line, all is okay

[oracle ~]$ perl -e 'use DBD::Oracle; print $DBD::Oracle::VERSION,"\n";'
Can't load
'/oracle/product/db/11.1/perl/lib/site_perl/5.8.3/x86_64-linux-thread-multi/auto/DBD/Oracle/Oracle.so'
for module DBD::Oracle: libclntsh.so.11.1: cannot open shared object file:
No such file or directory at
/usr/lib64/perl5/5.8.5/x86_64-linux-thread-multi/DynaLoader.pm line 230.
at -e line 1
Compilation failed in require at -e line 1.
BEGIN failed--compilation aborted at -e line 1.
[oracle ~]$ export LD_LIBRARY_PATH=/oracle/product/db/11.1/lib
[oracle ~]$ perl -e 'use DBD::Oracle; print $DBD::Oracle::VERSION,"\n";'
1.15

But if I do the following instead in the Perl script, it does not work? How
to set the LD_LIBRARY_PATH then?

$ENV{ORACLE_HOME}=$ORACLE_HOME;
$ENV{ORACLE_SID}=$ORACLE_SID;
$ENV{PATH}="$ORACLE_HOME/bin:$PATH";
$ENV{LD_LIBRARY_PATH}="$ORACLE_HOME/lib";

FYI, the script is to run from a cron which is why am setting
LD_LIBRARY_PATH in the script.

Any response will be very much appreciated. Thanks in advance.
Michael Ludwig
2010-05-28 09:05:41 UTC
Permalink
Post by newbie01 perl
Can someone advise how to set LD_LIBRARY_PATH from within the Perl scripts?
But if I do the following instead in the Perl script, it does not work? How
to set the LD_LIBRARY_PATH then?
$ENV{ORACLE_HOME}=$ORACLE_HOME;
$ENV{ORACLE_SID}=$ORACLE_SID;
$ENV{PATH}="$ORACLE_HOME/bin:$PATH";
$ENV{LD_LIBRARY_PATH}="$ORACLE_HOME/lib";
Try putting the %ENV adjustment in a BEGIN block that executes before you load the Oracle driver.
Post by newbie01 perl
FYI, the script is to run from a cron which is why am setting
LD_LIBRARY_PATH in the script.
You could do one of two things instead of tweaking %ENV in your Perl script:

(1) In your crontab, set the variables in the cronline:

* * * ... BLA=eins BLUB=zwei /usr/local/bin/script.pl

(2) Call a shell script from the crontab that sets up the environment for your Perl script and then calls it.

I'd go for (2).
--
Michael.Ludwig (#) XING.com
John Scoles
2010-05-28 10:14:38 UTC
Permalink
You will have to set those values before your modules load.

So you should stick them in the BEGIN and that should work

http://www.compuspec.net/reference/language/perl/BEGIN_and_END.shtml

cheers
John Scoles
Post by newbie01 perl
Hi all,
Can someone advise how to set LD_LIBRARY_PATH from within the Perl scripts?
If I set LD_LIBRARY_PATH from the command line, all is okay
[oracle ~]$ perl -e 'use DBD::Oracle; print $DBD::Oracle::VERSION,"\n";'
Can't load
'/oracle/product/db/11.1/perl/lib/site_perl/5.8.3/x86_64-linux-thread-multi/auto/DBD/Oracle/Oracle.so'
No such file or directory at
/usr/lib64/perl5/5.8.5/x86_64-linux-thread-multi/DynaLoader.pm line 230.
at -e line 1
Compilation failed in require at -e line 1.
BEGIN failed--compilation aborted at -e line 1.
[oracle ~]$ export LD_LIBRARY_PATH=/oracle/product/db/11.1/lib
[oracle ~]$ perl -e 'use DBD::Oracle; print $DBD::Oracle::VERSION,"\n";'
1.15
But if I do the following instead in the Perl script, it does not work? How
to set the LD_LIBRARY_PATH then?
$ENV{ORACLE_HOME}=$ORACLE_HOME;
$ENV{ORACLE_SID}=$ORACLE_SID;
$ENV{PATH}="$ORACLE_HOME/bin:$PATH";
$ENV{LD_LIBRARY_PATH}="$ORACLE_HOME/lib";
FYI, the script is to run from a cron which is why am setting
LD_LIBRARY_PATH in the script.
Any response will be very much appreciated. Thanks in advance.
--
Catch Alex & Sheeri at ODTUG/Kaleidoscope - June 27 - July 1.
Hear Sheeri speak or email ***@pythian.com to meet with Pythian.
Bobak, Mark
2010-05-29 16:19:02 UTC
Permalink
I'd argue you want to use a shell wrapper anyhow, because rather than setting those variables explicitly, you ought to do something like:
export ORACLE_SID=your_sid
export ORAENV_ASK=NO
. oraenv

and Oracle will set it all for you, and if/when something changes or is upgraded, your code will continue to do the right thing.

-Mark
________________________________________
From: Paul Johnson [***@pjcj.net]
Sent: Friday, May 28, 2010 12:33
To: John Scoles
Cc: newbie01 perl; beginners; dbi-users
Subject: Re: How to set LD_LIBRARY_PATH
Post by John Scoles
You will have to set those values before your modules load.
So you should stick them in the BEGIN and that should work
... except where it doesn't, such as on Solaris for example. Here,
LD_LIBRARY_PATH (at least) really does need to be set before the process
starts. You can do this by writing a shell wrapper, or re-execing your
perl script if the value is not already set.

You're using linux and I'm not sure if this sort of messing about is
required there.
Post by John Scoles
http://www.compuspec.net/reference/language/perl/BEGIN_and_END.shtml
cheers
John Scoles
Post by newbie01 perl
Hi all,
Can someone advise how to set LD_LIBRARY_PATH from within the Perl scripts?
If I set LD_LIBRARY_PATH from the command line, all is okay
[oracle ~]$ perl -e 'use DBD::Oracle; print $DBD::Oracle::VERSION,"\n";'
Can't load
'/oracle/product/db/11.1/perl/lib/site_perl/5.8.3/x86_64-linux-thread-multi/auto/DBD/Oracle/Oracle.so'
No such file or directory at
/usr/lib64/perl5/5.8.5/x86_64-linux-thread-multi/DynaLoader.pm line 230.
at -e line 1
Compilation failed in require at -e line 1.
BEGIN failed--compilation aborted at -e line 1.
[oracle ~]$ export LD_LIBRARY_PATH=/oracle/product/db/11.1/lib
[oracle ~]$ perl -e 'use DBD::Oracle; print $DBD::Oracle::VERSION,"\n";'
1.15
But if I do the following instead in the Perl script, it does not work? How
to set the LD_LIBRARY_PATH then?
$ENV{ORACLE_HOME}=$ORACLE_HOME;
$ENV{ORACLE_SID}=$ORACLE_SID;
$ENV{PATH}="$ORACLE_HOME/bin:$PATH";
$ENV{LD_LIBRARY_PATH}="$ORACLE_HOME/lib";
FYI, the script is to run from a cron which is why am setting
LD_LIBRARY_PATH in the script.
Any response will be very much appreciated. Thanks in advance.
--
Catch Alex & Sheeri at ODTUG/Kaleidoscope - June 27 - July 1.
--
Paul Johnson - ***@pjcj.net
http://www.pjcj.net
Peter J. Holzer
2010-05-31 13:52:21 UTC
Permalink
Post by Bobak, Mark
Post by John Scoles
You will have to set those values before your modules load.
So you should stick them in the BEGIN and that should work
... except where it doesn't, such as on Solaris for example. Here,
LD_LIBRARY_PATH (at least) really does need to be set before the
process starts. You can do this by writing a shell wrapper, or
re-execing your perl script if the value is not already set.
Have you considered doing a require instead of a use. With require,
the loading is done at run time, and would be governed by the
setting of LD_LIBRARY_PATH, at the time the require statement is
executed. Just set LD_LIBRARY_PATH before doing the require.
I'm afraid that you may have misunderstood what I wrote. There are
times when you really do need to set the variable before the process
starts.
I did not misunderstand what you wrote. My reasoning was that the
thing being loaded is a shared object (.so file). The system loader
(ld) has to be invoked for loading a shared object.
The .so file must be loaded into the (already running) perl process.
While that may be possible from an external process, it is simpler to do
it from the same process - so on the systems I know (Linux, Solaris) the
shared library loader is just a library function, not an external tool.

On Linux (at least i386[1]) the loader uses the current value of
LD_LIBRARY_PATH when it is asked to load an .so file. So you can change
LD_LIBRARY_PATH just before you want to load the library.

On Solaris the loader uses the value of LD_LIBRARY_PATH at program
startup. Changing LD_LIBRARY_PATH during runtime has no effect on the
process itself, just its children. I don't know why this is the case,
but I guess that LD_LIBRARY_PATH is split into components when the first
library (probably libc) and after that the components aren't used any
more.

hp


[1] I seem to remember that I ran into problems either on x86_64 or on
power, but I don't remember the details. If it's x86_64, I should be
able to test it (don't have access to power-based systems any more).
--
_ | Peter J. Holzer | Auf jedem Computer sollte der Satz Ludwigs II
|_|_) | Sysadmin WSR | eingeprägt stehen: "Ein ewig Rätsel will ich
| | | ***@wsr.ac.at | bleiben, mir und andern."
__/ | http://www.hjp.at/ | -- Wolfram Heinrich in desd
Peter J. Holzer
2011-01-24 14:49:49 UTC
Permalink
Post by Peter J. Holzer
On Linux (at least i386[1]) the loader uses the current value of
LD_LIBRARY_PATH when it is asked to load an .so file. So you can change
LD_LIBRARY_PATH just before you want to load the library.
On Solaris the loader uses the value of LD_LIBRARY_PATH at program
startup. Changing LD_LIBRARY_PATH during runtime has no effect on the
process itself, just its children. I don't know why this is the case,
but I guess that LD_LIBRARY_PATH is split into components when the first
library (probably libc) and after that the components aren't used any
more.
hp
[1] I seem to remember that I ran into problems either on x86_64 or on
power, but I don't remember the details. If it's x86_64, I should be
able to test it (don't have access to power-based systems any more).
Just for the record: That problem does exist on Linux/x86_64.

I just ran into the issue moving a bunch of CGI scripts from a
Linux/i386 box to a Linux/x86_64 box.

They do something like:

if (open(E, "$offl_root/dbi/env")) {
while (<E>) {
chomp;
my ($k, $v) = split(/=/);
$ENV{$k} = $v;
printlog('DEBUG', "setting $k=$v");
}
}
my ($data_source, $username, $auth) = read_cred("$offl_root/dbi/usradm");

my $dbh;
eval {
$dbh = DBI->connect($data_source, $username, $auth,
{ AutoCommit => 0,
PrintError => 1,
RaiseError => 1
}
);
};
if ($@) {
...
}

where $offl_root/dbi/env contains several environment variables, among
them ORACLE_HOME and LD_LIBRARY_PATH.

On Linux/i386 this works fine. On Linux/x86_64 it fails with the error
message

connection to dbi:Oracle:wpdb.wsr.ac.at as usradm failed:
install_driver(Oracle) failed: Can't load
'/usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi/auto/DBD/Oracle/Oracle.so'
for module DBD::Oracle: libocci.so.10.1: cannot open shared object file:
No such file or directory at
/usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/DynaLoader.pm line 230.

despite the fact that libocci.so.10.1 is in the LD_LIBRARY_PATH.

If I set LD_LIBRARY_PATH in the Apache config, it works as expected.

So I conclude that Linux/x86_64, like Solaris, but unlike Linux/i386,
ignores changes to LD_LIBRARY_PATH after a program is started.

hp
--
_ | Peter J. Holzer | Auf jedem Computer sollte der Satz Ludwigs II
|_|_) | Sysadmin WSR | eingeprägt stehen: "Ein ewig Rätsel will ich
| | | ***@wsr.ac.at | bleiben, mir und andern."
__/ | http://www.hjp.at/ | -- Wolfram Heinrich in desd
Jonathan Leffler
2010-05-31 14:53:46 UTC
Permalink
On Sun, May 30, 2010 at 10:47 AM, Marilyn Sander <
[...] My reasoning was that the thing being
loaded is a shared object (.so file). The system loader (ld) has to be
invoked for loading
a shared object. That seems to me to require a separate process, with an
environment
stack inherited from the Perl process that invokes it.
There's a problem here. What you describe is not what happens.

The system loader, ld, is used to create executables and shared objects. It
indeed is a separate program that is most often invoked automatically by a
compiler - GCC for example.

There is a wholly separate module, often with a name such as ld.so.1, which
is the dynamic library loader. It is actually a part of the program you are
running - Perl in the current context. It is responsible for loading other
shared libraries into the current process. Dynamically loading a shared
library adds the code to the current process; it does not invoke a separate
program/process.
--
Jonathan Leffler <***@gmail.com> #include <disclaimer.h>
Guardian of DBD::Informix - v2008.0513 - http://dbi.perl.org
"Blessed are we who can laugh at ourselves, for we shall never cease to be
amused."
j***@gmail.com
2010-05-28 15:32:27 UTC
Permalink
The dynamic loader read LD_LIBRARY_PATH when (before?) Perl gets going. AFAIK, it doesn't reread it, so changing it in Perl code is too late unless you set it and exec your code again (which is basically saying it is too late).

I'm tolerably certain this applies to Solaris; I think it applies elsewhere too.

JL


Sent from my BlackBerry® smartphone, powered by CREDO Mobile.

-----Original Message-----
From: newbie01 perl <***@gmail.com>
Date: Fri, 28 May 2010 19:45:14
To: beginners<***@perl.org>; dbi-users<dbi-***@perl.org>
Subject: How to set LD_LIBRARY_PATH

Hi all,

Can someone advise how to set LD_LIBRARY_PATH from within the Perl scripts?

If I set LD_LIBRARY_PATH from the command line, all is okay

[oracle ~]$ perl -e 'use DBD::Oracle; print $DBD::Oracle::VERSION,"\n";'
Can't load
'/oracle/product/db/11.1/perl/lib/site_perl/5.8.3/x86_64-linux-thread-multi/auto/DBD/Oracle/Oracle.so'
for module DBD::Oracle: libclntsh.so.11.1: cannot open shared object file:
No such file or directory at
/usr/lib64/perl5/5.8.5/x86_64-linux-thread-multi/DynaLoader.pm line 230.
at -e line 1
Compilation failed in require at -e line 1.
BEGIN failed--compilation aborted at -e line 1.
[oracle ~]$ export LD_LIBRARY_PATH=/oracle/product/db/11.1/lib
[oracle ~]$ perl -e 'use DBD::Oracle; print $DBD::Oracle::VERSION,"\n";'
1.15

But if I do the following instead in the Perl script, it does not work? How
to set the LD_LIBRARY_PATH then?

$ENV{ORACLE_HOME}=$ORACLE_HOME;
$ENV{ORACLE_SID}=$ORACLE_SID;
$ENV{PATH}="$ORACLE_HOME/bin:$PATH";
$ENV{LD_LIBRARY_PATH}="$ORACLE_HOME/lib";

FYI, the script is to run from a cron which is why am setting
LD_LIBRARY_PATH in the script.

Any response will be very muc
Oscar Gomez
2010-05-28 22:25:48 UTC
Permalink
create shell script, first set enviroment variables Oracle then
execute script perl
Post by j***@gmail.com
The dynamic loader read LD_LIBRARY_PATH when (before?) Perl gets going. AFAIK, it doesn't reread it, so changing it in Perl code is too late unless you set it and exec your code again (which is basically saying it is too late).
I'm tolerably certain this applies to Solaris; I think it applies elsewhere too.
JL
Sent from my BlackBerry® smartphone, powered by CREDO Mobile.
-----Original Message-----
Date: Fri, 28 May 2010 19:45:14
Subject: How to set LD_LIBRARY_PATH
Hi all,
Can someone advise how to set LD_LIBRARY_PATH from within the Perl scripts?
If I set LD_LIBRARY_PATH from the command line, all is okay
[oracle ~]$ perl -e 'use DBD::Oracle; print $DBD::Oracle::VERSION,"\n";'
Can't load
'/oracle/product/db/11.1/perl/lib/site_perl/5.8.3/x86_64-linux-thread-multi/auto/DBD/Oracle/Oracle.so'
No such file or directory at
/usr/lib64/perl5/5.8.5/x86_64-linux-thread-multi/DynaLoader.pm line 230.
at -e line 1
Compilation failed in require at -e line 1.
BEGIN failed--compilation aborted at -e line 1.
[oracle ~]$ export LD_LIBRARY_PATH=/oracle/product/db/11.1/lib
[oracle ~]$ perl -e 'use DBD::Oracle; print $DBD::Oracle::VERSION,"\n";'
1.15
But if I do the following instead in the Perl script, it does not work? How
to set the LD_LIBRARY_PATH then?
$ENV{ORACLE_HOME}=$ORACLE_HOME;
$ENV{ORACLE_SID}=$ORACLE_SID;
$ENV{PATH}="$ORACLE_HOME/bin:$PATH";
$ENV{LD_LIBRARY_PATH}="$ORACLE_HOME/lib";
FYI, the script is to run from a cron which is why am setting
LD_LIBRARY_PATH in the script.
Any response will be very much appreciated. Thanks in advance.
Loading...