使用 subprocess.call 运行批处理文件不起作用并冻结 IPython 控制台

Posted

技术标签:

【中文标题】使用 subprocess.call 运行批处理文件不起作用并冻结 IPython 控制台【英文标题】:Running batch file with subprocess.call does not work and freezes IPython console 【发布时间】:2022-01-08 09:07:27 【问题描述】:

这是一个常见问题,但阅读其他主题并没有为我解决问题。 我提供完整路径以确保我没有犯任何路径制定错误。

import subprocess    
# create batch script
myBat = open(r'.\Test.bat','w+') # create file with writing access
myBat.write('''echo hello
pause''') # write commands to file
myBat.close()

现在我尝试通过三种不同的方式运行它,在 SO 上找到了它们。在每种情况下,我的 IDE Spyder 都会进入忙碌模式并且控制台会冻结。没有弹出终端窗口或任何东西,没有任何反应。

subprocess.call([r'C:\\Users\\felix\\folders\\Batch_Script\\Test.bat'], shell=True)


subprocess.Popen([r'C:\\Users\\felix\\folders\\Batch_Script\Test.bat'], creationflags=subprocess.CREATE_NEW_CONSOLE)


p = subprocess.Popen("Test.bat", cwd=r"C:\\Users\\felix\\folders\\Batch_Script\\")
stdout, stderr = p.communicate()

每个都在有和没有shell=True 设置的情况下运行,也有和没有原始字符串、单个反斜杠等。你能看出为什么这行不通吗?

【问题讨论】:

检查行的结尾是\r\n 而不仅仅是\n,因为它是windows shell 所需要的。可能还想调用@ECHO off 以使用subprocess.run 清理输出。 Spyder 中的行尾设置是CRLF,这是正确的,对吧?我对其他命令也有同样的问题,没有回显。 idk... 编写文件,然后用记事本++ 打开它并查看隐藏字符以检查。它可能取决于语言环境......我必须修复它 好的,我可以确认它是 echo helloCRLFpause 所以这似乎是正确的,而不是原因 【参考方案1】:

Spyder 并不总是能正确处理标准流,因此使用subprocess.call 时看不到输出并不让我感到惊讶,因为它通常在同一个控制台中运行。在外部 cmd 提示符下执行它为什么对你有用也是有道理的。

如果您想继续使用 spyder 终端,但要为您的 bat 脚本调出一个新窗口,您应该使用以下内容

subprocess.call(["start", "test.bat"], shell=True)

start 启动单独的命令提示符窗口以运行指定的程序或命令。您需要shell=True,因为它是内置的 cmd 而不是程序本身。然后,您可以像往常一样将您的 bat 文件传递​​给它。

【讨论】:

先生,您是英雄。谢谢!【参考方案2】:

    你应该使用 open()...

    使用 open(r'.\Test.bat','w+') 作为 myBat: myBat.write('echo hello\npause') # 将命令写入文件

    我在 ide 之外测试了这一行(通过在 cmd 中运行),它将打开一个新的 cmd 窗口

    subprocess.Popen([r'Test.bat'], creationflags=subprocess.CREATE_NEW_CONSOLE)

【讨论】:

在 cmd 窗口中,这也适用于我。但是,不是来自 IDE。你知道是什么原因造成的吗? Spyder 5.1.5 在这里 ... @Felix IDE 的标准流重定向(stdout、stdin、stderr)非常复杂,spyder 5.2.0 做了一些改进,但在最新版本中仍然不起作用。【参考方案3】:

嘿,我已经解决了你的问题:)

不要使用subprocess,而是使用os

例子:

import os
myBatchFile = f"start /max + yourFile.bat"
system(myBatchFile)
# "start /max" will run your batch file in new window in fullscreen mode

如果有帮助,请稍后感谢我:)

【讨论】:

什么是开始?它对我说未定义,是否缺少某些内容?你的意思是myBatchFile = "start /max" + "Test.bat" 吗?这对我不起作用。如果我不这样调整它,我的代码会出现语法错误。 如果你不介意它不被附加到任何东西上,你可以使用 os.system() @BenMoskovitch 我已经这样做了,因为这个修复很明显。虽然不能解决未定义的“开始”命令。 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。 @Felix "Start" 将在 Windows 的新窗口中启动该批处理文件,这完全是可选的,我也像你说的那样向他推荐了操作系统

以上是关于使用 subprocess.call 运行批处理文件不起作用并冻结 IPython 控制台的主要内容,如果未能解决你的问题,请参考以下文章

subprocess.call未按预期运行

是否有 subprocess.call 的安静版本?

非阻塞 subprocess.call

将更多/多个参数传递给 Python subprocess.call [重复]

subprocess.call 路径问题,如何解决?

subprocess.call 使用