我是python的新手,想要打开一个windows cmd提示符,启动一个进程,让进程保持运行状态,然后向同一个运行进程发出命令。
命令会改变,所以我不能在下面的cmdline变量中包含这些命令。此外,该过程需要10-15秒才能启动,因此我不想浪费时间等待进程每次启动和运行命令。只想开始一次处理。并在同一过程中根据需要运行快速命令
我希望使用subprocess.Popen
来完成这项工作,尽管我对更好的方法持开放态度。请注意,我的运行流程不是cmd,但我只是以此为例
import subprocess
cmdline = ['cmd', '/k']
cmd = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
cmd.stdin.write("echo hi") #would like this to be written to the cmd prompt
print cmd.stdout.readline() #would like to see 'hi' readback
cmd.stdin.write("echo hi again") #would like this to be written to the cmd prompt
print cmd.stdout.readline() #would like to see 'hi again' readback
结果不是我所期望的。好像stdin.write命令实际上并没有进入,并且readline冻结而没有任何东西可读。
我尝试过popen.communicate()
而不是写/读取,但它会杀死进程。我已经尝试在Popen行中设置bufsize,但这并没有太大的区别
答案 0 :(得分:1)
您的评论表明您通过stdin输入混淆命令行参数。也就是说,system-console.exe
程序接受script=filename
参数这一事实并不意味着您可以通过stdin向命令发送与命令相同的字符串,例如,python
可执行文件接受-c "print(1)"
命令 - 如果你将它作为命令传递给Python shell,那么它是一个SyntaxError
。
因此,第一步是使用正确的语法。假设system-console.exe
自己接受文件名:
#!/usr/bin/env python3
import time
from subprocess import Popen, PIPE
with Popen(r'C:\full\path\to\system-console.exe -cli -',
stdin=PIPE, bufsize=1, universal_newlines=True) as shell:
for _ in range(10):
print('capture.tcl', file=shell.stdin, flush=True)
time.sleep(5)
注意:如果您重定向了多个流,例如stdin,stdout,那么您应该同时读取/写入两个流(例如,使用多个线程),否则很容易使程序死锁。
相关:
subprocess
,pexpect
模块读取多个输出的代码示例。第二步和以下步骤可能必须处理子进程一侧的缓冲问题(在Windows上不受欢迎),system-console
是否允许重定向其stdin / stdout或者是否与其一起使用直接控制台和字符编码问题(管道中的各种命令如何编码文本)。
答案 1 :(得分:0)
如果您想实时查看输出,则需要使用它:
import subprocess
cmdline = ['cmd', '/k']
cmd = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
cmd.stdin.write("echo hi\n")#would like this to be written to the cmd prompt
for line in iter(cmd.stdout.readline,""):
print line
cmd.stdin.write("echo hi again\n")#would like this to be written to the cmd prompt
不确定您要做什么,但如果您想在获得某些输出时输入某些数据,那么我建议您使用pexpect
答案 2 :(得分:0)
以下是我测试过的一些代码,它们正在使用Windows 10,Quartus Prime 15.1和Python 3.5
import subprocess
class altera_system_console:
def __init__(self):
sc_path = r'C:\altera_lite\15.1\quartus\sopc_builder\bin\system-console.exe --cli --disable_readline'
self.console = subprocess.Popen(sc_path, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
def read_output(self):
rtn = ""
loop = True
i = 0
match = '% '
while loop:
out = self.console.stdout.read1(1)
if bytes(match[i],'utf-8') == out:
i = i+1
if i==len(match):
loop=False
else:
rtn = rtn + out.decode('utf-8')
return rtn
def cmd(self,cmd_string):
self.console.stdin.write(bytes(cmd_string+'\n','utf-8'))
self.console.stdin.flush()
c = altera_system_console()
print(c.read_output())
c.cmd('set jtag_master [lindex [get_service_paths master] 0]')
print(c.read_output())
c.cmd('open_service master $jtag_master')
print(c.read_output())
c.cmd('master_write_8 $jtag_master 0x00 0xFF')
print(c.read_output())