我在这里拉我的头发。我正在生成一个需要 Python 反馈的进程。
当我在 cmd 窗口中运行命令时,它运行良好,但是当我尝试通过 Python 运行它时,终端挂起。
p = subprocess.Popen(startcmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(out, err) = p.communicate()
Run Code Online (Sandbox Code Playgroud)
在startcmdPython 控制台中打印的字符串在哪里,如下所示:
"C:/Program Files/GRASS GIS 7.2.1/grass72.bat" --version
Run Code Online (Sandbox Code Playgroud)
如果我将其复制并粘贴到 Windows cmd 中,它会显示版本信息并在大约一秒钟后将控制权返回到命令提示符,但在 Python 中它会冻结。
我应该指出,如果我用startcmd类似"dir"或什至"python --version"这样的东西替换字符串,它工作正常!
附加:我试过shell=True,这有相同的结果。
附加:我尝试将 cmd 和参数作为数组发送,如下面的答案中所建议的那样shell=False,但这也同样挂起。
附加:我已将 GRASS 路径添加到系统路径,因此现在我可以简单地grass72 --version在 cmd 窗口中调用以获取结果,但是这在 Python 中仍然冻结,但在 cmd 中工作正常。
附加:我创建了一个基本的 .bat 文件来测试 .bat 文件是否通过 Python 运行正常,这是我创建的:
@echo off
title Test Batch Script
echo I should see this message
Run Code Online (Sandbox Code Playgroud)
这在 cmd 和 Python 中都运行良好。
问题发现但没有解决!
因此,我正在运行subprocess.Popen使用 Python 3.6生成进程的脚本。生成的 .bat 文件使用 GRASS 附带的 Python 版本(基于 2.7)启动 Python 脚本:
%GRASS_PYTHON% "\BLAH\BLAH\grass72.py"
Run Code Online (Sandbox Code Playgroud)
有趣的是,如果我subprocess.Popen使用 Python 2.7启动脚本,它运行良好。啊哈,你可能会想,解决了!但这并不能解决我的问题——因为我真的需要 Python 3.6 来启动这个过程,为什么 Python 的哪个版本启动批处理文件很重要?无论如何,生成的新 Python 脚本是使用 Python 2.7 启动的。
自从我开始重定向 stdout 后,我可以看到在使用 Python 3.6 启动进程时出现错误:
File "C:\ProgramData\Anaconda3\lib\site.py", line 177
file=sys.stderr)
^
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)
注意它恢复到 Anaconda3!即使它是使用 2.7 中的 python.exe 启动的!
Bło*_*tek -1
尝试这个:
p = subprocess.Popen(startcmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
Run Code Online (Sandbox Code Playgroud)