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

16 投票
4 回答
21770 浏览
提问于 2025-04-17 14:39

我正在写一个程序,需要在Linux和Windows上都能运行,并且要使用在路径中存在的可执行文件(假设是这样)。

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

像这样的代码,在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)

我在控制台中收到了错误信息:

'makeblastdb' is not recognized as an internal or external command,
operable program or batch file.

尽管我可以通过cmd.exe运行相同的命令,但即使设置shell=False,我也得到了相同的反馈。

有没有什么办法可以运行这个命令,假设可执行文件在PATH环境变量中?谢谢!

4 个回答

5

我自己也为这个问题苦恼过,直到我发现了这个Python的错误报告

报告中提到:“如果你在Windows上把一个目录添加到PATH里,并且这个目录是用引号括起来的,subprocess就找不到里面的可执行文件。”因为Windows并不需要引号,所以去掉引号就解决了我的问题(在2.7版本中)。

9

你可以通过传递一个包含环境变量的映射,来控制新创建的子进程中可用的环境变量,这个映射是通过env这个参数来实现的。例如:

proc = subprocess.Popen(args, env={'PATH': '/some/path'})

或者,如果你只想从系统环境中继承PATH这个变量,而不想把其他的系统环境变量都带上,可以这样做:

proc = subprocess.Popen(args, env={'PATH': os.getenv('PATH')})

不过,直接使用绝对路径可能会更简单一些。

6

好的,下面是我让它工作的方式。

env = os.environ
proc = subprocess.Popen(args, env=env)

撰写回答