2009-07-24 10 views
20

Czy można zmienić zmienne środowiskowe bieżącego procesu?Zmień bieżące środowisko procesu LD_LIBRARY_PATH

Dokładniej w skrypcie Pythona Chcę zmienić LD_LIBRARY_PATH tak że na import module „x”, która jest uzależniona od pewnego xyz.so, xyz.so pochodzi z mojego danej ścieżki w LD_LIBRARY_PATH

jest jakiś inny sposób dynamicznie zmieniać ścieżkę, z której ładowana jest biblioteka?

Edit: Chyba muszę wspomnieć, że już próbował coś takiego os.environ [ "LD_LIBRARY_PATH"] = mojasciezka os.putenv ('', LD_LIBRARY_PATH mojasciezka)

ale te modyfikują env. dla zrodził sub-procesem, a nie obecnego procesu i ładowaniem modułów nie uważa nowy LD_LIBRARY_PATH

Edit2, więc pytanie brzmi, możemy zmienić otoczenie lub coś tak ładowarka biblioteka widzi go i ładuje stamtąd?

+0

Czy to nie jest duplikatem http://stackoverflow.com/questions/856116/changing-ldlibrarypath-at-runtime -for-ctypes? W rzeczywistości nie pytasz, jak zmienić środowisko, ale raczej jak zmienić miejsce, w którym Python ładuje biblioteki. –

+0

ok! Powiem, że to jest duplikat, ale nie jest to kwestia zmiany środowiska, np. w aplikacji, która ładuje dynamiczną bibliotekę A, możemy zmienić środowisko tak, aby A było ładowane z naszej ścieżki wyboru –

Odpowiedz

32

Powodem

os.environ["LD_LIBRARY_PATH"] = ... 

nie działa jest prosta: tę zmienną kontroluje zachowanie dynamicznego ładowarki (ld-linux.so.2 w systemach Linux, Solaris) ld.so.1, ale ładowarka wygląda tylko na LD_LIBRARY_PATH raz przy starcie procesu . Zmiana wartości LD_LIBRARY_PATH w bieżącym procesie po ten punkt nie ma żadnego efektu (tak jak odpowiada odpowiedź na pytanie this).

Macie jakieś opcje:

A. Jeśli wiesz, że będziesz potrzebować xyz.so z /some/path oraz kontrolować wykonanie skryptu Pythona od samego początku, a potem po prostu ustawić LD_LIBRARY_PATH do własnych upodobań (po sprawdzenie, czy jeszcze nie jest tak ustawione) i ponowne wykonanie się. To właśnie robi Java.

B. Można importować /some/path/xyz.so poprzez ścieżki bezwzględnej przed importowania x.so. Kiedy następnie zaimportujesz x.so, program ładujący wykryje, że załadował już xyz.so, i użyje już załadowanego modułu zamiast szukać go ponownie.

C. Jeśli budować x.so siebie, możesz dodać do swojej linii -Wl,-rpath=/some/path łącza, a następnie importowanie x.so spowoduje ładowarka szukać modułów zależnych w /some/path.

+0

B, wygląda jak opcja, którą mogę użyć –

+0

W jaki sposób zostanie zastosowana opcja B? Myślę, że OP zakładał, że '/ some/path/xyz.so' jest biblioteką współdzieloną, od której zależy moduł Pythona; 'xyz.so' nie zawiera samego modułu Python. Mam podobną sytuację i nie znam żadnego sposobu importowania biblioteki w sposób, który opisujesz. –

+2

@JasonR Opcja B może być zaimplementowana za pomocą 'import dl; dl.open ("/ some/path/xyz.so") ' –

-4

dobrze, zmienne środowiskowe są przechowywane w słowniku os.environ, więc jeśli chcesz zmienić, można zrobić

os.environ["PATH"] = "/usr/bin" 
+0

. I myślę, że musisz upewnić się, że ustawiłeś os.environ ["LD_LIBRARY_PATH"] * przed * poleceniem importu dla moduł x. – ThomasH

+0

zobacz edycję, już wypróbowałem to i to nie zadziałało –

+0

Ustawienie LD_LIBRARY_PATH w taki sposób nie wpływa na bieżący proces, jak wyjaśniłem w mojej odpowiedzi. –

0

Z mojego doświadczenia próbuje zmienić sposób ładowarka pracuje dla uruchomionego Pythona jest bardzo podstępny; prawdopodobnie zależy od systemu operacyjnego/wersji; może nie działać. Jednym z rozwiązań, które mogą pomóc w pewnych okolicznościach, jest uruchomienie pod-procesu, który zmienia parametr środowiska za pomocą skryptu powłoki, a następnie uruchamia nowy Python za pomocą powłoki.

8

Na podstawie odpowiedzi z zatrudnionych rosyjskim, to co działa na mnie

oracle_libs = os.environ['ORACLE_HOME']+"/lib/" 
rerun = True 

if not 'LD_LIBRARY_PATH' in os.environ: 
    os.environ['LD_LIBRARY_PATH'] = ":"+oracle_libs 
elif not oracle_libs in os.environ.get('LD_LIBRARY_PATH'): 
    os.environ['LD_LIBRARY_PATH'] += ":"+oracle_libs 
else: 
    rerun = False 

if rerun: 
    os.execve(os.path.realpath(__file__), sys.argv, os.environ) 
+1

Sztuczka execve jest * dokładnie * to, czego potrzebowałem i działa, przekaż głos! –