2009-07-24 12 views
20

¿Es posible cambiar las variables de entorno del proceso actual?Cambiar la LD_LIBRARY_PATH del entorno de proceso actual

manera más específica en un script en Python que quieren cambiar LD_LIBRARY_PATH de manera que la importación de un módulo de 'x' que depende de alguna xyz.so, xyz.so se toma de mi ruta dada en LD_LIBRARY_PATH

¿Hay alguna otra manera de cambiar dinámicamente la ruta desde donde se carga la biblioteca?

Editar: Creo que necesito mencionar que ya he intentado algo así os.environ [ "LD_LIBRARY_PATH"] = miruta os.putenv ('LD_LIBRARY_PATH', miruta)

pero éstos modificar el env. para el sub-proceso creado, no el proceso actual y la carga del módulo no tiene en cuenta el nuevo LD_LIBRARY_PATH

Edit2, por lo que la pregunta es si podemos cambiar el medio ambiente o algo por lo que el gestor de bibliotecas percibe y se carga a partir de ahí?

+0

No es éste un duplicado de http://stackoverflow.com/questions/856116/changing-ldlibrarypath-at-runtime -for-ctypes? En realidad, no está preguntando cómo cambiar el entorno, sino cómo cambiar desde dónde python carga las bibliotecas. –

+0

bien! Diré que esto es un duplicado, pero no, no se trata de Python sobre el cambio de entorno, p. en la aplicación de CA que carga una lib dinámica A, podemos cambiar el entorno para que A se cargue desde nuestra ruta de elección –

Respuesta

32

La razón

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

que no funciona es simple: este entorno controles comportamiento variable del cargador dinámico (ld-linux.so.2 en Linux, Solaris ld.so.1 en), pero el cargador sólo se ve en LD_LIBRARY_PATH una vez al iniciar el proceso de . Cambiando el valor de LD_LIBRARY_PATH en el proceso actual después de ese punto no tiene ningún efecto (tal como dice la respuesta a la pregunta this).

Usted tiene algunas opciones:

A. Si sabe que va a necesitar xyz.so de /some/path, y controlar la ejecución del script en Python, desde el principio, entonces basta con establecer LD_LIBRARY_PATH a su gusto (después de comprobando que aún no está configurado) y vuelva a ejecutar usted mismo. Esto es lo que hace Java.

B. Puede importar /some/path/xyz.so a través de su ruta absoluta antes de importando x.so. Cuando importe x.so, el cargador descubrirá que ya ha cargado xyz.so, y usará el módulo ya cargado en lugar de buscarlo de nuevo.

C. Si se construye x.so usted mismo, usted puede agregar -Wl,-rpath=/some/path a su línea de enlace, y luego importar x.so hará que el cargador para buscar los módulos dependientes en /some/path.

+0

B, parece una opción que puedo usar –

+0

¿Cómo se implementaría la opción B? Creo que el OP implicó que '/ some/path/xyz.so' es una biblioteca compartida de la que depende un módulo de Python; 'xyz.so' no contiene un módulo Python en sí. Tengo una situación similar y no conozco ninguna forma de importar la biblioteca de la manera que usted describe. –

+2

@JasonR La opción B podría implementarse usando 'import dl; dl.open ("/ some/path/xyz.so") ' –

-4

así, las variables de entorno se almacenan en la os.environ diccionario, por lo que si desea cambiar, puede hacerlo

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

Y creo que debe asegurarse de configurar os.environ ["LD_LIBRARY_PATH"] * antes * de la instrucción de importación para módulo x. – ThomasH

+0

ver la edición, ya lo he intentado y esto no funcionó –

+0

Establecer LD_LIBRARY_PATH de esa manera no afecta el proceso actual, como expliqué en mi respuesta. –

0

En mi experiencia tratando de cambiar la forma en que el cargador funciona para un funcionamiento Python es muy complicado; probablemente dependiente de OS/versión; puede que no funcione. Una solución alternativa que podría ayudar en algunas circunstancias es iniciar un subproceso que modifique el parámetro de entorno mediante un script de shell y luego lanzar un nuevo Python utilizando el shell.

8

Sobre la base de la respuesta de Rusia ocupada, esto es lo que funciona para mí

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

El truco de execve es * exactamente * lo que necesitaba, y funciona, tener un voto positivo! –

Cuestiones relacionadas