Subprocess.call或Subprocess.Popen不能使用PATH中的可执行文件(Linux/Windows)

Jac*_*ang 13 python windows shell subprocess

我正在编写一个需要在Linux和Windows上运行的程序,并使用路径中存在的可执行文件(带参数).(假定)

目前,我在使用Subprocess.Call和Subprocess.Popen在Windows中运行可执行文件时遇到问题.

对于像这样的代码,在Windows 8中

def makeBlastDB(inFile, inputType, dbType, title, outDir):
    strProg = 'makeblastdb'
    strInput = '-in ' + inFile
    strInputType = '-input_type ' + inputType
    strDBType = '-dbtype ' + dbType
    strTitle = '-title ' + title
    strOut = '-out ' + os.path.join(os.sep, outDir, title)
    cmd = [strProg, strInput, strInputType, strDBType, strTitle, strOut]
    result = Popen(cmd, shell=True)
Run Code Online (Sandbox Code Playgroud)

我在控制台中收到错误消息

'makeblastdb' is not recognized as an internal or external command,
operable program or batch file.
Run Code Online (Sandbox Code Playgroud)

即使我可以使用cmd.exe运行相同的命令,我得到相同的响应shell = False.

假设可执行文件在PATH环境变量中,我是如何运行命令的任何想法?谢谢

wim*_*wim 8

您可以通过使用envkeyword参数传递映射来控制生成的子流程中可用的环境变量.例如

proc = subprocess.Popen(args, env={'PATH': '/some/path'})
Run Code Online (Sandbox Code Playgroud)

或者PATH从系统环境变量继承,而不必从系统环境中删除其他所有内容:

proc = subprocess.Popen(args, env={'PATH': os.getenv('PATH')})
Run Code Online (Sandbox Code Playgroud)

但是,使用绝对路径可能更容易/更简单.


Jac*_*ang 7

好的,我是如何让它工作的.

env = os.environ
proc = subprocess.Popen(args, env=env)
Run Code Online (Sandbox Code Playgroud)

  • 如果我没有弄错,这没有净效果,因为"[Popen]的默认行为是继承当前进程'环境". (2认同)

jos*_*hua 5

我自己为此苦苦挣扎,直到找到了这个python bug报告

“如果在Windows上的PATH中添加目录,以便该目录用引号引起来,则子进程在其中找不到可执行文件。” 由于Windows不需要引号,因此删除引号即可解决我的问题(在2.7版中)。

  • 有趣的是-这也许可以解释为什么添加shell = True似乎常常可以解决此问题。 (2认同)