2011-12-28 2 views
10

Я не могу использовать %ENV var на моем скрипте Perl для использования Oracle libs.% ENV не работает, и я не могу использовать общую библиотеку

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

Если я печатаю $ENV{'ORACLE_HOME'} и $ENV{'LD_LIBRARY_PATH'} все кажется хорошо, но, когда я бегу мой сценарий у меня есть ошибка:

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 на веб-я видел, что правильный способ установить окр вары на Perl использовать %ENV хеш.

Экспорт ORACLE_HOME и LD_LIBRARY_PATH через оболочку unix (export LD_LIBRARY_PATH=...) он работает правильно. Любой совет?

+0

Прошло много времени с тех пор, как мне пришлось работать с Oracle и Perl, и я помню, что одна из библиотек, которые нуждается в модуле Perl, не устанавливается с установкой разработчика. Мне пришлось бы извлечь файлы и вытащить библиотеку из пакета базы данных. –

+0

Но странно, потому что, если я экспортирую эти пути через оболочку, он работает правильно. Кажется, проблема не связана с отсутствующими библиотеками. – Daniele

+0

Оболочка оболочки оболочки - это то, как мы всегда это делали. –

ответ

10

Значение переменной LD_LIBRARY_PATH должно быть установлено до Ваша программа запускается - до загрузки perl. Изменение его в BEGIN{} повлияет на новые программы, которые вы начнете, но это не повлияет на загрузку разделяемых библиотек - в этом случае (хотя я никогда не использовал DBD :: Oracle) вы загружаете Oracle .so в уже запущенную программу, поэтому «слишком поздно» изменить LD_LIBRARY_PATH. Динамический компоновщик /lib/ld.so (или так) запускается до perl, поэтому к моменту составления вашего скрипта и запускается BEGIN{}, он уже настроен.

Вы могли попытаться повторно EXEC сценарий как своего собственного преемника или что-то *, но короткий сценарий оболочки почти наверняка будет самым простым решением:

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

* - это было бы своего рода сумасшедший, но 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

Большое вам спасибо. Он отлично работает – Daniele

-1

Я только что прошел через нечто подобное. Я должен был убедиться, что среда Oracle была настроена до того, как ее еще называют. Убедитесь, что блок BEGIN находится перед любыми другими операциями использования. В моем случае что-то вызывалось в файле httpd.conf Apache, поэтому мне пришлось настраивать свою среду там, а не в моем пакете.

+0

Да, мой блок 'BEGIN' находится перед всем – Daniele

+0

Это в веб-среде? Если это так, возможно, что что-то загружает DBD :: Oracle, прежде чем он сделает это для вашего скрипта. – gpojd

+0

Нет, это не в веб-среде. Это просто сценарий, который я запускаю из оболочки – Daniele

1

Я написал несколько сценариев тестирования, чтобы убедиться, что среда создается при изменении %ENV:

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

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

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

Это печатает:

printing out bar-bar 

, который я ожидал.

Затем я попытался это:

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

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


system qq(./test.sh); 

и создал test.sh программу, которая выглядит следующим образом:

#! /bin/sh 

echo This is what I got: $FOO; 

В этом случае, мой сценарий Perl работает test.sh, которая выводит значение из $FOO переменная среды, которая была установлена ​​в моем скрипте Perl.Бег test.pl я получаю:

This is what I got bar-bar 

Это показывает, что не только устанавливает Perl переменные среды, но она также экспортирует эти переменные, так называемые скрипты имеют доступ к ним.

Вы можете попробовать подобный прием, чтобы убедиться, что оба параметра LD_LIBRARY_PATH и ORACLE_HOME устанавливаются перед использованием. Я подозреваю, что вы обнаружите, что это действительно происходит, но ваша программа все еще не работает, когда вы устанавливаете %ENV.

Это указывает на один вывод: настройка среды для LD_LIBRARY_PATH и ORACLE_HOME может произойти слишком поздно к моменту запуска скрипта Perl. Я считаю, что операционная система проверяет LD_LIBRARY_PATH до начала Perl. Я нашел, что это делает поиск на 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.

Так, LD_LIBRARY_PATH для разделяемой библиотеки загрузчика ld.so выполнения, если ld.so уже загружен, изменения LD_LIBRARY_PATH ничего не будет делать.

Я нашел подобное обсуждение на Perl Monks. Я заметил, что кто-то нашел rerunning env, похоже, сработал.

0

Одно из решений состоит в изменении /etc/ld.so.conf

На CentOS/RHEL 6.4, вы можете создать и т.д./ld.so.conf.d/оракулу с этим:

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

Очевидно, измените, как подходит ваш ORACLE_HOME.

Затем запустите

ldconfig -v 
0

Вы можете поместить export команды в сценарий запуска для оболочки Unix, которые вы должны иметь разрешение на редактирование. Таким образом, переменные окружения будут заданы всякий раз, когда вы запускаете новую оболочку, и все сценарии и программы, использующие Oracle, будут их подбирать.

Смежные вопросы