当我在Ubuntu中使用os.system("./mydemo")
调用python中的可执行文件时,它找不到mydemo所需的.so文件(libmsc.so)。我使用了os.system("export LD_LIBRARY_PATH=pwd:$LD_LIBRARY_PATH;")
,但它仍然找不到libmsc.so。
libmsc.so在当前目录中。不应该是全球性的。
执行os.system("export LD_LIBRARY_PATH=pwd:$LD_LIBRARY_PATH;")
时,运行shell的新实例,在那里更改LD_LIBRARY_PATH
,然后立即退出。此外,pwd在Python上下文中没有任何意义。
尝试这样设置env变量:
os.system("LD_LIBRARY_PATH={} ./mydemo".format(os.getcwd()))
或者使用子流程模块更好?
import subprocess
env = os.environ.copy()
env['LD_LIBRARY_PATH'] = os.getcwd()
proc = subprocess.Popen("./mydemo", shell=True, env=env)
proc.wait()
如果我没记错,通过os.system
执行export ...
只会在作用域内设置该shell变量,因此它在以下os.system
作用域中不可用。在执行Python脚本之前,应该在shell中设置LD_LIBRARY_PATH
。
Btw。也避免设置相对路径…
问题是export
只将其变量导出到当前shell的子级。就像在您通过调用os.system
创建的shell中一样,它会立即退出。
如果你想要最简单的修复程序来实现这一点,你可以在一个shell中同时执行export
和目标程序:
os.system("export LD_LIBRARY_PATH=pwd:$LD_LIBRARY_PATH; ./mydemo")
这还有其他一些问题。例如,export
在同一命令中创建和分配变量是一种bash
主义,可能并非在所有shell中都可用。使用subprocess
,您可以指定一个特定的shell,但使用system
,您只需要获得操作系统认为的默认shell——在Linux上,手册页上说这意味着/bin/sh -c
。
实际上,解决这个问题的最好方法是首先不使用shell,并按照您想要的方式设置环境变量。这正是为什么os.system
文档说:"subprocess
模块为生成新流程和检索其结果提供了更强大的功能;使用该模块比使用该功能更可取。"例如:
env = dict(os.environ)
env['LD_LIBRARY_PATH'] = '"{}":{}'.format(
os.getcwd(), env.get('LD_LIBRARY_PATH', ''))
subprocess.check_call(['./mydemo'], env=env)
或者,如果你想真正安全(不像你的外壳代码):
LD_LIBRARY_PATH = env.get('LD_LIBRARY_PATH', '')
if LD_LIBRARY_PATH:
LD_LIBRARY_PATH = ':' + LD_LIBRARY_PATH
LD_LIBRARY_PATH = shlex.quote(os.getcwd()) + LD_LIBRARY_PATH
subprocess.check_call(['./mydemo'], env=env)
我已经比你通常写的更明确、更详细地写了这篇文章,以使步骤变得显而易见:不要在空路径之前包含尾随的:
,并在有人对当前工作目录做了一些棘手的事情时使用shlex.quote
。