Setting LD_LIBRARY_PATH from inside Python

Yaroslav Bulatov picture Yaroslav Bulatov · Jul 1, 2011 · Viewed 43k times · Source

Is there a way to set specify during runtime where Python looks for shared libraries?

I have fontforge.so located in fontforge_bin and tried the following

os.environ['LD_LIBRARY_PATH']='fontforge_bin'
sys.path.append('fontforge_bin')
import fontforge

and get

ImportError: fontforge_bin/fontforge.so: cannot open shared object file: No such file or directory

Doing ldd on fontforge_bin/fontforge.so gives the following

linux-vdso.so.1 =>  (0x00007fff2050c000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00007f10ffdef000)
libc.so.6 => /lib/libc.so.6 (0x00007f10ffa6c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f110022d000)

Answer

Will Pierce picture Will Pierce · Aug 23, 2014

Your script can check for the existence/properness of the environment variable before you import your module, then set it in os.environ if it is missing, and then call os.execv() to restart the python interpreter using the same command line arguments but an updated set of environment variables.

This is only advisable before any other imports (other than os and sys), because of potential module-import side-effects, like opened file descriptors or sockets, which may be challenging to close cleanly.

This code sets LD_LIBRARY_PATH and ORACLE_HOME:

#!/usr/bin/python
import os, sys
if 'LD_LIBRARY_PATH' not in os.environ:
    os.environ['LD_LIBRARY_PATH'] = '/usr/lib/oracle/XX.Y/client64/lib'
    os.environ['ORACLE_HOME'] = '/usr/lib/oracle/XX.Y/client64'
    try:
        os.execv(sys.argv[0], sys.argv)
    except Exception, exc:
        print 'Failed re-exec:', exc
        sys.exit(1)
#
# import yourmodule
print 'Success:', os.environ['LD_LIBRARY_PATH']
# your program goes here

It's probably cleaner to set that environment variable as part of the starting environment (in the parent process or systemd/etc job file).