web-dev-qa-db-ja.com

pythonでインポートする前にLD_LIBRARY_PATHを設定します

PythonはPYTHONPATH環境変数を使用して、モジュールを探すフォルダーを決定します。 _sys.path_を変更することで、それをいじることができます。これは、純粋なPythonモジュールでうまく機能します。しかし、モジュールが共有オブジェクトファイルまたは静的ライブラリを使用する場合、_LD_LIBRARY_PATH_(Linux上)でそれらを探しますが、これは簡単に変更できず、私の知る限りプラットフォームに依存します。

この問題の簡単な修正方法は、環境変数を設定するか、_LD_LIBRARY_PATH=. ./script.py_のようなスクリプトを呼び出すことですが、新しいシェルを開くたびに再度設定する必要があります。また、私の場合の_.so_ファイルは常に_.py_ファイルと同じディレクトリにありますが、別の絶対パスに移動される可能性があるため、毎回自動的に設定したいと思いますスクリプトを呼び出します。

Pythonインタプリタが実行時にプラットフォームに依存せずにライブラリを探すパスを編集するにはどうすればよいですか?

編集:

私はすでにos.environ['LD_LIBRARY_PATH'] = os.getcwd()を試しましたが、役に立ちませんでした。

34
iFreilicht

私は使うだろう:

import os

os.environ['LD_LIBRARY_PATH'] = os.getcwd()  # or whatever path you want

これにより、LD_LIBRARY_PATH現在のプロセスの実行の継続時間/ライフタイムのみの環境変数。

EDIT:Pythonを起動する前にこれを設定する必要があるように見えます: ctypesの実行時にLD_LIBRARY_PATHを変更する

そのため、ラッパーを使用することをお勧めします.sh(または.py主張する場合)スクリプト。また、@ chepnerが指摘したように、.soファイル(virtualenv内の)標準の場所にあります。

Python内部からのLD_LIBRARY_PATHの設定 も参照してください。

20
Erik Allik

この問題に対する私の解決策は、これをPythonスクリプト(通常のシバンの代わりに)の最初の行として置くことです:

exec env LD_LIBRARY_PATH=/some/path/to/lib /path/to/specific/python -x "$0" "$@"

そして、これがどのように機能するかです:

  • shebangがない場合、現在のシェルはファイルをシェルスクリプトとして扱います。
  • 「exec」は、この最初の行がシェルによって実行されるこのファイルの最後のコマンドであることを保証します。
  • 「env」は、環境変数を設定するためにここで使用されます。 LD_LIBRARY_PATH、
  • pythonのインタープリターへの正確なパスを指定するか、「env」がPATHで見つけることができます。
  • 「-x」はPythonのオプションであり、Pythonインタープリターによって最初の行が無視されます。
  • 「$ 0」はスクリプト名、「$ @」は位置パラメータに置き換えられます。
7
Jarek

Pythonは、os.environ[‘LD_LIBRARY_PATH’]またはos.environ[‘PATH’]のように環境変数の値を取得すると、その値を、親プロセスの環境から辞書にコピーします。通常はbash(bashプロセスの環境は子プロセスに引き継がれます) 、python実行中のインスタンス)。

この環境変数セクションは、bashからのenvコマンド出力で確認できます。

環境変数を変更した後に無限ループ(/proc/<pid>/environ)を導入することにより、while 1: passからこのenvデータを表示/読み取りすることもできます。

pythonスクリプト内で変更した後に/proc/<pid>/environからこの変数値/データを表示/読み取りすると、実際の変数のデータは変更されないことがわかります。 pythonスクリプトは、変更された辞書キー値を示し、更新されます。

os.environ['LD_LIBRARY_PATH']='/<new_location>'のように、pythonスクリプト内のenv変数を変更すると実際に起こるのは、プロセスのenv変数セクションにマッピングされないローカル辞書の値を更新するだけです。 。ローカルディクショナリのみが変更/更新/設定されたため、現在のプロセスの環境に反映するまでずっと伝播しません。

したがって、新しい環境変数を反映させる場合は、execvを使用して、プロセスのメモリイメージを新しい環境変数データで上書きする必要があります。

例:

new_lib = '/<new_location>'
if not new_lib in os.environ['LD_LIBRARY_PATH']:
    os.environ['LD_LIBRARY_PATH'] += ':'+new_lib
    try:
        os.execv(sys.argv[0], sys.argv)
    except Exception as e:
        sys.exit('EXCEPTION: Failed to Execute under modified environment, '+e)

import xyz
#do something else

制限:理想的には、pythonはos.environ変数のそのような変更を許可しません。しかし、定数辞書データ型がないため、データの変更を許可します変数:execvが使用されない限り、実行中のプロセスの実際の環境に反映するのに何の有用性もないため、値を変更することは絶対にありません。

3
S471