10

%ENVPerlスクリプトでvarを使用してOracleライブラリを使用することはできません。

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)が失敗しました:モジュールDBD ::Oracleの「/usr/local/lib64/perl5/auto/DBD/Oracle/Oracle.so」をロードできません:libclntsh.so.10.1:共有オブジェクトファイルを開くことができません:いいえそのようなファイルまたはディレクトリ(/usr/lib64/perl5/DynaLoader.pm行200)。at(eval 3)行3コンパイルがrequire at(eval 3)行3で失敗しました。必要な共有ライブラリまたはdllが予期した場所にインストールされていない可能性があります。 persistence.perlの22行目

Webで検索すると、Perlでenv変数を設定する正しい方法は%ENVハッシュを使用することであることがわかりました。

エクスポートORACLE_HOMELD_LIBRARY_PATHてunixシェル(export LD_LIBRARY_PATH=...)を介して正しく動作します。何かアドバイス?

4

5 に答える 5

11

プログラムを開始する前、つまりプログラム自体をロードする前にLD_LIBRARY_PATH環境変数を設定する必要があります。変更すると、起動する新しいプログラムに影響しますが、共有ライブラリのロードには影響しません。この場合(DBD :: Oracleを使用したことはありませんが)、すでに実行中のOracleにOracleをロードしています。プログラムなので、を変更するには「遅すぎます」。ダイナミックリンカ(またはそれ以上)は前に開始されるため、スクリプトがコンパイルされて実行されるまでに、スクリプトはすでに設定されています。perlBEGIN{}.soLD_LIBRARY_PATH/lib/ld.soperlBEGIN{}

スクリプトを独自の後継者または何か*として再実行することもできますが、短いシェルスクリプトが最も簡単な解決策になることはほぼ間違いありません。

  #!/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 { $0 } $0 => @ARGV;
  }
于 2011-12-28T15:46:52.457 に答える
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スクリプトが実行されており、Perlスクリプトで設定された環境変数test.shの値が出力されます。$FOO実行中test.pl私は得る:

This is what I got bar-bar

これは、Perlが環境変数を設定しているだけでなく、それらの変数をエクスポートしていること、いわゆるシェルスクリプトがそれらにアクセスできることを示しています。

同様の手法を試して、LD_LIBRARY_PATHORACLE_HOMEが使用される前に両方が設定されていることを確認できます。これは実際に起こっていることに気付くと思いますが、を設定してもプログラムはまだ機能していません%ENV

これは1つの結論を示しています。Perlスクリプトが開始するまでに環境を設定するのが遅すぎる可能性がありますLD_LIBRARY_PATH。Perlが起動する前にORACLE_HOMEオペレーティングシステムが調べていると思います。LD_LIBRARY_PATH私はこれが検索をしているのを見つけましたLD_LIBRARY_PATH

LD_LIBRARY_PATHは、ランタイム共有ライブラリローダー(ld.so)に共有ライブラリを検索するときに検索する追加のディレクトリセットを提供するために設定する環境変数です。コロン(:)で区切って、複数のディレクトリを一覧表示できます。このリストは、特定の実行可能ファイルのコンパイル済みローダーパスの既存のリスト、およびシステムのデフォルトのローダーパスの前に追加されます。

つまり、ランタイム共有ライブラリローダーLD_LIBRARY_PATH用です。すでにロードされている場合、変更しても何も起こりません。ld.sold.soLD_LIBRARY_PATH

PerlMonksについても同様の議論を見つけました。誰かが再実行envが機能しているように見えることに気づきました。

于 2011-12-28T16:30:34.820 に答える
1

1つの解決策は、/ etc/ld.so.confを変更することです。

CentOS / RHEL 6.4では、次のようにetc / ld.so.conf.d/oracleを作成できます。

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

もちろん、ORACLE_HOMEに合わせて変更してください。

次に実行します

ldconfig -v
于 2013-09-24T22:01:14.490 に答える
0

export編集する権限が必要なUNIXシェルの起動スクリプトにコマンドを入れることができます。そうすれば、新しいシェルを起動するたびに環境変数が設定され、Oracleを使用するすべてのスクリプトとプログラムがそれらを取得します。

于 2017-10-04T16:05:12.427 に答える
-1

私はちょうど似たようなことを経験しました。Oracle環境が他の人から呼ばれる前にセットアップされていることを確認する必要がありました。BEGINブロックが他の「use」ステートメントの前にあることを確認してください。私の場合、Apacheのhttpd.confファイルで何かが呼び出されていたため、パッケージではなく、そこで環境をセットアップする必要がありました。

于 2011-12-28T14:23:44.293 に答える