Python3.7使用subprocess模块向已打开cmd发送命令报TimeoutExpired异常问题
问题根因
- 代码中使用了
start命令:start是Windows shell内置命令,作用是独立启动新进程,你通过subprocess.Popen拿到的process对象,实际是执行start命令的临时shell进程,不是弹出的cmd窗口对应的进程,所以往process.stdin写的内容根本送不到目标cmd窗口。 - 就算进程绑定正确,输入的命令末尾没有加换行符
\n:cmd只有收到换行符才会判定为输入完成、执行对应命令。 process.communicate()方法会等待目标进程结束才返回,你启动的cmd窗口如果没有主动退出,自然会触发10秒超时。
解决方案
如果需求是启动可见的cmd窗口,且能持续往窗口发送命令执行,参考如下代码:
import subprocess import time # 直接启动cmd进程,不通过start命令,默认会弹出可见窗口 process = subprocess.Popen( ['cmd', '/k', 'dir'], # /k参数指执行完dir后不关闭cmd stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True ) # 模拟其他操作执行耗时 time.sleep(2) # 发送命令,末尾必须加换行符 cmd = 'date\n' process.stdin.write(cmd) process.stdin.flush() # 必须执行flush,否则内容会停留在缓冲区没发送到cmd # 后续要发送其他命令重复write+flush操作即可 # 要关闭cmd窗口可发送exit命令 # process.stdin.write('exit\n') # process.stdin.flush() # process.wait()
注意事项
- 不要用
input作为变量名,会覆盖Python内置的input()函数。 - 不要频繁混用
stdin.write和communicate方法,communicate只能调用一次,调用后会关闭管道,无法再发送新命令。 - 如果不需要保留cmd窗口,把
/k参数换成/c,cmd执行完命令后会自动退出。
内容的提问来源于stack exchange,提问作者Costi
相关产品推荐
相关产品推荐

