2011-12-28 12 views
10

No puedo usar %ENV var en mi script de Perl para usar las librerías de Oracle.% ENV no funciona y no puedo usar la biblioteca compartida

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; 
}; 

Si imprimo $ENV{'ORACLE_HOME'} y $ENV{'LD_LIBRARY_PATH'} todo parece bien, pero, cuando ejecuto mi script que tengo el 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

búsqueda en la web vi que la forma correcta de establecer env vars en Perl es usar hash %ENV.

Exportando ORACLE_HOME y LD_LIBRARY_PATH a través del shell Unix (export LD_LIBRARY_PATH=...) funciona correctamente. ¿Algún consejo?

+0

Ha pasado mucho tiempo desde que tuve que trabajar con Oracle y Perl y recuerdo que una de las bibliotecas que necesita el módulo Perl no se instala con la instalación del desarrollador. Tendría que extraer los archivos y sacar la biblioteca del paquete de la base de datos. –

+0

Pero es extraño, porque si exporto esas rutas a través de shell, funciona correctamente. Parece que no hay un problema relacionado con las bibliotecas que faltan – Daniele

+0

El envoltorio del script de Shell es la forma en que siempre lo hicimos. –

Respuesta

10

La variable de entorno LD_LIBRARY_PATH tiene que ser establecido antes de inicia su programa - antes perl en sí está cargado. Cambiarlo en BEGIN{} afectará a los nuevos programas que empiece, pero no afectará la carga de bibliotecas compartidas - en este caso (aunque nunca he usado DBD :: Oracle) está cargando un Oracle .so en el programa que ya se está ejecutando, por lo que es "demasiado tarde" para cambiar el LD_LIBRARY_PATH. El vinculador dinámico /lib/ld.so (más o menos) se inicia antes de perl, por lo que cuando se compila el script y se ejecuta BEGIN{}, ya está configurado.

Usted podría tratar de volver a exec su guión como su propio sucesor o algo *, pero un script que es casi seguro que va a ser la solución más simple:

#!/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 "[email protected]" 

* - esto sería un poco loco, pero TIMTOWTDI:

eval { 
    use DBD::Oracle foo bar baz; … 
    }; 
    if ([email protected] =~ /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\[email protected]\n"; 
    exec { $0 } $0 => @ARGV; 
    } 
+0

Muchas gracias. Funciona a la perfección – Daniele

-1

Acabo de pasar por algo similar. Tenía que asegurarme de que el entorno Oracle estuviera configurado antes de que cualquier otra cosa lo llamara. Asegúrese de que el bloque BEGIN esté antes de cualquier otra declaración de "uso". En mi caso, algo se llamaba en el archivo httpd.conf de Apache, así que tuve que configurar mi entorno allí en lugar de en mi paquete.

+0

Sí, mi bloque 'BEGIN' está antes que todo – Daniele

+0

¿Esto es en un entorno web? Si es así, es posible que algo cargue DBD :: Oracle antes de que llegue a su script. – gpojd

+0

No, no está en un entorno web. Es solo un script que ejecuto desde shell – Daniele

1

escribí un par de scripts de prueba para verificar que el medio ambiente está siendo ajustado cuando se cambia %ENV:

use strict; 
use warnings; 
use feature qw(say); 

BEGIN { 
    my $foo = "bar-bar"; 
    $ENV{FOO} = "$foo"; 
} 

system qq(/bin/echo printing out \$FOO); 

Esto muestra:

printing out bar-bar 

que es lo que esperaba.

entonces yo probamos este:

use strict; 
use warnings; 
use feature qw(say); 

BEGIN { 
    my $foo = "bar-bar"; 
    $ENV{FOO} = "$foo"; 
} 


system qq(./test.sh); 

y creó un programa test.sh que tiene este aspecto:

#! /bin/sh 

echo This is what I got: $FOO; 

En este caso, mi script de Perl se está ejecutando test.sh que imprime el valor de la $FOO variable de entorno que se estableció en mi secuencia de comandos de Perl.Correr test.pl me sale:

This is what I got bar-bar 

Esto demuestra que no sólo es la creación de Perl las variables de entorno, sino que también es la exportación de esas variables, denominadas secuencias de comandos shell tiene acceso a ellos.

Puede probar una técnica similar para verificar que LD_LIBRARY_PATH y ORACLE_HOME se están configurando antes de ser utilizados. Sospecho que descubrirá que esto está sucediendo, pero que su programa aún no funciona cuando configure %ENV.

Esto apunta a una conclusión: Configurar el entorno para LD_LIBRARY_PATH y ORACLE_HOME puede estar ocurriendo demasiado tarde cuando se inicia el script de Perl. Creo que el sistema operativo examina LD_LIBRARY_PATH antes de que comience Perl. Me pareció que esta haciendo una búsqueda en LD_LIBRARY_PATH:

LD_LIBRARY_PATH is an environment variable you set to give the run-time shared library loader (ld.so) an extra set of directories to look for when searching for shared libraries. Multiple directories can be listed, separated with a colon (:). This list is prepended to the existing list of compiled-in loader paths for a given executable, and any system default loader paths.

Así, LD_LIBRARY_PATH es para el tiempo de ejecución ld.so biblioteca compartida cargador, ld.so Si ya se ha cargado, el cambio de LD_LIBRARY_PATH no hará nada.

Encontré un debate similar en Perl Monks. Noté que alguien encontró que rerunning env parecía funcionar.

0

Una solución es modificar /etc/ld.so.conf

en CentOS/RHEL 6.4, puede crear etc/ld.so.conf.d/Oracle con esto:

/oracle/sw/product/11.2.0/dbhome_1/lib 

Obviamente, modifique según su ORACLE_HOME.

A continuación, ejecute

ldconfig -v 
0

se puede poner los comandos export en el script de arranque para su shell de Unix, que usted debe tener permiso para editar. De esta forma, las variables de entorno se establecerán cada vez que inicie un nuevo shell y todos los scripts y programas que usen Oracle los detectarán.

Cuestiones relacionadas