为什么Python Popen使用不同的可执行文件
我在这台电脑上有两个不同版本的程序。我无法删除旧版本,因为我没有管理员权限,但我把新版本放在了我家目录的'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 中的下一个文件。