【发布时间】:2017-12-06 12:00:34
【问题描述】:
我在这里拉头发。我正在生成一个需要 Python 反馈的过程。
当我在 cmd 窗口中运行命令时,它运行良好,但是当我尝试通过 Python 运行它时,终端挂起。
p = subprocess.Popen(startcmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(out, err) = p.communicate()
startcmd 是一个字符串,在 Python 控制台中打印时如下所示:
"C:/Program Files/GRASS GIS 7.2.1/grass72.bat" --version
如果我将其复制并粘贴到 Windows cmd 中,它会显示版本信息并在大约一秒钟后将控制权返回到命令提示符,但在 Python 中它会冻结。
我应该指出,如果我将startcmd 字符串替换为"dir" 甚至"python --version",它可以正常工作!
补充:我试过shell=True,结果一样。
附加:我已经尝试将 cmd 和参数作为数组发送,正如下面的答案中所建议的那样,shell=False,但这也同样挂起。
附加:我已将 GRASS 路径添加到系统 PATH,因此现在我可以在 cmd 窗口中简单地调用 grass72 --version 来获得结果,但这在 Python 中仍然会冻结,但是在 cmd 中运行良好。
补充:我创建了一个基本的 .bat 文件来测试 .bat 文件是否可以通过 Python 运行,这是我创建的:
@echo off
title Test Batch Script
echo I should see this message
这在 cmd 和 Python 中都可以正常运行。
发现但未解决的问题!
所以,我正在运行使用 Python 3.6 使用subprocess.Popen 生成进程的脚本。生成的 .bat 文件使用 GRASS 附带的 Python 版本(基于 2.7)启动 Python 脚本:
%GRASS_PYTHON% "\BLAH\BLAH\grass72.py"
有趣的是,如果我使用 Python 2.7 启动 subprocess.Popen 脚本,它可以正常工作。啊哈,你可能会想,解决了!但这并不能解决我的问题——因为我真的需要 Python 3.6 来启动该进程,为什么 Python 的哪个版本启动批处理文件很重要?无论如何,生成的新 Python 脚本是使用 Python 2.7 启动的。
自从我开始重定向标准输出后,我可以看到当我使用 Python 3.6 启动进程时出现错误:
File "C:\ProgramData\Anaconda3\lib\site.py", line 177
file=sys.stderr)
^
SyntaxError: invalid syntax
注意它恢复到 Anaconda3!即使它是使用 2.7 的 python.exe 启动的!
【问题讨论】:
-
您正在运行的命令是否产生大量输出?
subprocess.PIPE可以容纳多少文本是有限制的,如果已满,它将阻止该过程。 -
不,它比 dir 创建的要少得多。它只有一行。
-
如果将
startcmd替换为cmd.exe /c "C:\\Program Files\\GRASS GIS 7.2.1\\grass72.bat" --version会怎样? -
顺便说一句,如果您进行一些基本调试以确定: 1. 您观察到的行为是特定于
grass72.bat还是打印输出显示的简单.bat脚本会很有用相同的行为。如果特定于grass72.bat,则尝试找出原因。 2.使用subprocess.PIPE是否重要。 -
我实际上正在调查中,谢谢。首先我会尝试你的建议然后再回来。