views:

465

answers:

5

Is it possible to change current process environment variable?

More specifically in a python script I want to change LD_LIBRARY_PATH so that on import of a module 'x' which depends on some xyz.so, xyz.so is taken from my given path in LD_LIBRARY_PATH

is there any other way to dynamically change path from where library is loaded?

Edit: I think I need to mention that i have already tried thing like os.environ["LD_LIBRARY_PATH"] = mypath os.putenv('LD_LIBRARY_PATH', mypath)

but these modify the env. for spawned sub-proces, not the current process and module loading doesn't consider the new LD_LIBRARY_PATH

Edit2, so question is can we change environment or something so the library loader sees it and loads from there?

A: 

Yes you can change current process environment. (with pythonian analog of setenv - modifying environ)

EFraim
+1  A: 

well, the environment variables are stored in the dictionary os.environ, so if you want to change , you can do

os.environ["PATH"] = "/usr/bin"
And I think you have to make sure you set os.environ["LD_LIBRARY_PATH"] *before* the import statement for module x.
ThomasH
see the edit, i have already tried this and this did not work
Anurag Uniyal
Setting LD_LIBRARY_PATH in such fashion does not affect current process, as I explained in my answer.
Employed Russian
+1  A: 

You should change os.environ. There is also a os.putenv call, but calling putenv() directly does not change os.environ, so it’s better to modify os.environ:

import os
home_lib_dir = os.path.join(os.environ["HOME"], "lib")
if os.path.exists(home_lib_dir):
    os.environ["LD_LIBRARY_PATH"] = os.environ["LD_LIBRARY_PATH"] + ":" + home_lib_dir

See http://docs.python.org/library/os.html for the details

I think the loading of libraries depends on how the Python module is doing it as well, perhaps you could give more details?

David Fraser
see the edit, i have already tried this and this did not work, suppose module is simple c module which links to a dynamic lib, which lib it loads will depend on LD_LIBRARY_PATH
Anurag Uniyal
A: 

In my experience trying to change the way the loader works for a running Python is very tricky; probably OS/version dependent; may not work. One work-around that might help in some circumstances is to launch a sub-process that changes the environment parameter using a shell script and then launch a new Python using the shell.

Aaron Watters
+2  A: 

The reason

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

doesn't work is simple: this environment variable controls behavior of the dynamic loader (ld-linux.so.2 on Linux, ld.so.1 on Solaris), but the loader only looks at LD_LIBRARY_PATH once at process startup. Changing the value of LD_LIBRARY_PATH in the current process after that point has no effect (just as the answer to this question says).

You do have some options:

A. If you know that you are going to need xyz.so from /some/path, and control the execution of python script from the start, then simply set LD_LIBRARY_PATH to your liking (after checking that it is not already so set), and re-execute yourself. This is what Java does.

B. You can import /some/path/xyz.so via its absolute path before importing x.so. When you then import x.so, the loader will discover that it has already loaded xyz.so, and will use the already loaded module instead of searching for it again.

C. If you build x.so yourself, you can add -Wl,-rpath=/some/path to its link line, and then importing x.so will cause the loader to look for dependent modules in /some/path.

Employed Russian
B, looks like an option I can use
Anurag Uniyal