Reputation: 63
On macOS Sierra 10.12.6, environment variable LD_LIBRARY_PATH
cannot be used by os.system()
, subprocess.run()
and subprocess.Popen()
, even though PATH
can be used normally. Python version is 3.6.1
. But on Linux(Ubuntu 17.10), this environment variable can also be used rightly. The following python script envv.py
can show this problem:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import subprocess
import os
import time
PATH = "PATH"
print(os.environ.get(PATH))
os.system("echo $" + PATH)
subprocess.run("echo $" + PATH, shell=True)
subprocess.run("/bin/echo $" + PATH, shell=True)
subprocess.run("/bin/echo $" + PATH, shell=True, env={PATH: os.environ.get(PATH)})
subprocess.run("/bin/echo $" + PATH, shell=True, env=os.environ)
subprocess.Popen("/bin/echo $" + PATH, shell=True, env=os.environ.copy())
time.sleep(2)
print('\n')
LD_LIBRARY_PATH = "LD_LIBRARY_PATH"
print(os.environ.get(LD_LIBRARY_PATH))
os.system("echo $" + LD_LIBRARY_PATH)
subprocess.run("/bin/echo $" + LD_LIBRARY_PATH, shell=True)
subprocess.run("/bin/echo $" + LD_LIBRARY_PATH, shell=True, env={LD_LIBRARY_PATH: os.environ.get(LD_LIBRARY_PATH)})
subprocess.run("/bin/echo $" + LD_LIBRARY_PATH, shell=True, env=os.environ)
subprocess.Popen("/bin/echo $" + LD_LIBRARY_PATH, shell=True, env=os.environ.copy())
time.sleep(2)
print('\n')
On macOS, the output is
$ python3 envv.py
/opt/alps/bin:...
/opt/alps/bin:...
/opt/alps/bin:...
/opt/alps/bin:...
/opt/alps/bin:...
/opt/alps/bin:...
/opt/alps/bin:...
/opt/alps/lib:...
$ # use $ to show blank line
$
....
On Linux, the output is
$ python3 envv.py
/opt/intel/compilers_and_libraries_2018.1.163/linux/bin/intel64:...
/opt/intel/compilers_and_libraries_2018.1.163/linux/bin/intel64:...
/opt/intel/compilers_and_libraries_2018.1.163/linux/bin/intel64:...
/opt/intel/compilers_and_libraries_2018.1.163/linux/bin/intel64:...
/opt/intel/compilers_and_libraries_2018.1.163/linux/bin/intel64:...
/opt/intel/compilers_and_libraries_2018.1.163/linux/bin/intel64:...
/opt/intel/compilers_and_libraries_2018.1.163/linux/bin/intel64:...
/opt/intel/compilers_and_libraries_2018.1.163/linux/compiler/lib/intel64:...
/opt/intel/compilers_and_libraries_2018.1.163/linux/compiler/lib/intel64:...
/opt/intel/compilers_and_libraries_2018.1.163/linux/compiler/lib/intel64:...
/opt/intel/compilers_and_libraries_2018.1.163/linux/compiler/lib/intel64:...
/opt/intel/compilers_and_libraries_2018.1.163/linux/compiler/lib/intel64:...
/opt/intel/compilers_and_libraries_2018.1.163/linux/compiler/lib/intel64:...
Does anyone have any idea? Thanks a lot!
UPDATE 2018-02-07
Follow @GrahamDumpleton 's suggestion, I tried DYLD_LIBRARY_PATH
, but got the same result. The test stript is
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import subprocess
import os
DYLD_LIBRARY_PATH = "DYLD_LIBRARY_PATH"
print(os.environ.get(DYLD_LIBRARY_PATH))
os.system("echo $" + DYLD_LIBRARY_PATH)
subprocess.run("/bin/echo $" + DYLD_LIBRARY_PATH, shell=True)
subprocess.run("/bin/echo $" + DYLD_LIBRARY_PATH, shell=True, env={DYLD_LIBRARY_PATH: os.environ.get(DYLD_LIBRARY_PATH)})
subprocess.run("/bin/echo $" + DYLD_LIBRARY_PATH, shell=True, env=os.environ)
subprocess.Popen("/bin/echo $" + DYLD_LIBRARY_PATH, shell=True, env=os.environ.copy())
And the related output is
$ python3 envv.py
/opt/intel/compilers_and_libraries_2018.1.126/mac/compiler/lib:...
$
$
...
Upvotes: 4
Views: 3666
Reputation: 48
If you're using subprocess.Popen
with shell=True
, you can manually propagate the LD_LIBRARY_PATH
and DYLD_LIBRARY_PATH
variables like so:
import os
import sys
import subprocess
cmd = "/bin/echo $DYLD_LIBRARY_PATH"
sys_env = os.environ.copy()
# We've used os.environ.copy() so we can make mods
# to the subprocess environment if needed without
# affecting the parent process.
if sys.platform == 'darwin':
if "LD_LIBRARY_PATH" in sys_env:
cmd = f"export LD_LIBRARY_PATH={sys_env['LD_LIBRARY_PATH']} && {cmd}"
if "DYLD_LIBRARY_PATH" in sys_env:
cmd = f"export DYLD_LIBRARY_PATH={sys_env['DYLD_LIBRARY_PATH']} && {cmd}"
process = subprocess.Popen(
cmd,
env=sys_env,
shell=True,
)
Upvotes: 2