Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I've inherited a script that uses DBI to talk to Oracle. Currently, it works fine but only if in I first export ORACLE_HOME and LD_LIBRARY_PATH in my shell. Otherwise I get this:

install_driver(Oracle) failed: Can't load '/share/sun/perl/lib/site_perl/5.005/sun4-solaris/auto/DBD/Oracle/Oracle.so' for module DBD::Oracle: ld.so.1: my-dbi_cmd: fatal: libclntsh.so.8.0: open failed: No such file or directory at /share/sun/perl/lib/5.00502/sun4-solaris/DynaLoader.pm line 168.

I tried assigning $ENV{'ORACLE_HOME'} and $ENV{'LD_LIBRARY_PATH'} in the script; and after that I can system("set |egrep 'ORACLE_HOME|LD_LIBRARY_PATH'"), but I still get the error.

I tried assigning them and then forking off a child to connect, and still get the error.

Surely there is a graceful way to do this within perl?

Replies are listed 'Best First'.
Re: %ENV and DBI
by almut (Canon) on Mar 28, 2008 at 16:36 UTC

    On Solaris, changing LD_LIBRARY_PATH from within a process doesn't work, because the dynamic linker is caching the info. In other words, you have to set it before, e.g. in a shell wrapper, or some such. Fork-and-exec (as opposed to simply forking) should also work though, I suppose.

    Update: As to re-exec-ing yourself, here's one way you could do it (tested on Solaris 10):

    #!/usr/bin/perl BEGIN { my $orahome = "/path/to/orahome"; my $oralib = "$orahome/lib"; unless ($ENV{LD_LIBRARY_PATH} =~ /$oralib/) { $ENV{ORACLE_HOME} = $orahome; $ENV{LD_LIBRARY_PATH} = $oralib; exec $0, @ARGV; } } use DBD::Oracle;
      Thanks almut! I was close. Instead of this:
      $ENV{ORACLE_HOME} = $orahome; $ENV{LD_LIBRARY_PATH} = $oralib; exec $0, @ARGV;

      I was trying this:
      exec("export ORACLE_HOME=$orahome LD_LIBRARY_PATH=$oralib; $0");

      Thanks again, your solution works.
Re: %ENV and DBI
by perrin (Chancellor) on Mar 28, 2008 at 15:33 UTC
    You're probably setting them too late. Do it in a BEGIN block before the "use DBD::Oracle" line.
      Thank you, perrin. I tried this:

      #!/usr/bin/perl BEGIN { #$ENV{'ORACLE_HOME'} = '/path/to/orahome'; #$ENV{'LD_LIBRARY_PATH'} = '/path/to/orahome/lib'; system("export ORACLE_HOME=/path/to/orahome"); system("export LD_LIBRARY_PATH=/path/to/orahome/lib"); }; use DBI;
      I still get the error using the two system calls or the two $ENV assignments. Any other thoughts?

        Because you've commented out the two lines that might have done something and instead started two subshells in which you modify the environment (and then those subshells promptly exit making no difference whatsoever in the parent or any of its descendants).

        The cake is a lie.
        The cake is a lie.
        The cake is a lie.