为什么Python Popen使用不同的可执行文件

1 投票
2 回答
543 浏览
提问于 2025-04-17 21:20

我在这台电脑上有两个不同版本的程序。我无法删除旧版本,因为我没有管理员权限,但我把新版本放在了我家目录的'bin'文件夹里(这个文件夹在我的$PATH中是第一个)。

我试着用Python的Popen来调用它,

Popen(['clingo'...]...)

结果运行得很好。

但是后来我需要在调用之前设置一个环境变量,所以我把'clingo'重命名为'run_clingo',并在'bin'目录里用一个脚本替换了它:

# File: ~/bin/clingo
export LD_LIBRARY_PATH=/usr/local/gcc4.8.1/lib64:$LD_LIBRARY_PATH
run_clingo $@

当我从终端运行'clingo'时,它运行得很好,但Python的Popen却调用了旧版本(它在$PATH中排在后面)。

我该怎么做才能让Popen调用正确的版本呢?为什么把一个可执行文件改成脚本会导致Popen去别的地方找呢?

2 个回答

1

我猜测可能是因为Popen使用的路径和你在终端里用的不一样。我建议你检查一下脚本的第一行(也就是shebang行,通常以#!开头),有时候人们会在这里写env -i python,这表示它要求使用一个空的,也就是默认的环境。

另外要注意的是,使用subprocess.call是更推荐的做法,而不是直接使用Popen

2

~/bin/clingo 文件的最上面加上这行代码 #!/bin/sh,然后运行:

$ chmod +x ~/bin/clingo

这样可以让这个文件变得可以执行。

Popen() 会调用 os.execvp() 来执行一个程序。它的行为和你的命令行有点不同,因为命令行会模拟 execvp() 的功能:如果脚本的最上面没有加 shebang(就是 !#.. 这一行),那么命令行会把它当作一个脚本重新运行,但 Python 的 os.execvp() 会直接去执行 PATH 中的下一个文件。

撰写回答