我使用 os.system 运行可执行文件,但它需要一个 .so 文件,它找不到库



当我在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

相关内容

最新更新