%ENV не работает, и я не могу использовать общую библиотеку
Я не могу использовать %ENV
var в моем скрипте Perl для использования 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;
};
если я распечатаю $ENV{'ORACLE_HOME'}
и $ENV{'LD_LIBRARY_PATH'}
все кажется ок, но, когда я запускаю свой скрипт, у меня есть ошибка:
install_driver(для Oracle) ошибка: не удается загрузить '/usr/местные/lib64/perl5/авто/ДБР/Оракул/Оракул.поэтому для модуля ДБР::Оракул: libclntsh.так.10.1: невозможно открыть разделяемый объектный файл: нет такого файла или каталога в /usr/lib64/perl5/DynaLoader.линия часов 200. at (eval 3) строка 3 Сборник ошибка в require at (eval 3) строка 3. Возможно, требуемая общая библиотека или dll не установлена там, где ожидалось при настойчивости.строки в Perl 22
поиск в Интернете я видел, что правильный способ установить env vars на Perl-использовать %ENV
хэш.
экспорт ORACLE_HOME
и LD_LIBRARY_PATH
через оболочку unix (export LD_LIBRARY_PATH=...
) он работает правильно. Есть советы?
5 ответов
на LD_LIBRARY_PATH
переменная окружения должна быть установлена до ваша программа начинается - перед загружается. Изменение его в BEGIN{}
повлияет новый - программы что вы начинаете, но это не повлияет на загрузку общие библиотеки - в этом случае (хотя я никогда не использовал DBD::Oracle) вы загружаете Oracle .so
в уже запущенную программу, поэтому" слишком поздно " менять LD_LIBRARY_PATH
. Динамический компоновщик /lib/ld.so
(или так) запускается до perl
, поэтому к моменту компиляции вашего скрипта и BEGIN{}
работает, он уже настроен.
вы мог бы попробуйте повторно выполнить свой скрипт как собственный преемник или что-то*, но короткий сценарий оболочки почти наверняка будет самым простым решением:
#!/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 "$@"
* - это было бы немного сумасшедшим, но TIMTOWTDI:
eval {
use DBD::Oracle foo bar baz; …
};
if ($@ =~ /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\n$@\n";
exec { } => @ARGV;
}
я написал несколько тестовых сценариев, чтобы проверить, что среда устанавливается при изменении %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 скрипт. Бег!--9--> Я:
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-это переменная среды, которую вы установили в дайте загрузчику общей библиотеки времени выполнения (ld.Итак) дополнительный набор каталогов для поиска при поиске общих библиотек. Множественный каталоги могут быть перечислены, разделены двоеточием (:). Этот список добавляется к существующему списку скомпилированных путей загрузчика для данного исполняемого файла и к любым системным путям загрузчика по умолчанию.
и LD_LIBRARY_PATH
на ld.so
загрузчик общей библиотеки времени выполнения, если ld.so
уже загружен, изменение LD_LIBRARY_PATH
ничего не сделает.
я нашел аналогичное обсуждение на сайте На Perl Монахи. Я заметил, что кто-то нашел повторный запуск env
казалось, работали.
выход один-изменить файл /etc/ЛД.так.конф
на CentOS / RHEL 6.4 вы можете создать etc / ld.Итак.conf.d / oracle с этим:
/oracle/sw/product/11.2.0/dbhome_1/lib
очевидно, измените, как подходит вашему ORACLE_HOME.
затем запустите
ldconfig -v
вы могли бы поставить export
команды в сценарий запуска для вашей оболочки unix, который вы должны иметь разрешение на редактирование. Таким образом, переменные среды будут устанавливаться при запуске новой оболочки, и все сценарии и программы, использующие Oracle, будут получать их.
Я только что прошел через что-то подобное. Я должен был убедиться, что среда Oracle была настроена, прежде чем что-либо еще называлось это. Убедитесь, что BEGIN
блок находится перед любыми другими операторами "use". В моем случае что-то вызывалось в httpd Apache.conf-файл, поэтому мне пришлось настроить мою среду там, а не в моем пакете.