我正在尝试运行可执行文件并使用subprocess.Popen;捕获其输出;但是,我似乎并没有获得全部输出。
subprocess.Popen
import subprocess as s from subprocess import Popen import os ps = Popen(r'C:\Tools\Dvb_pid_3_0.exe', stdin = s.PIPE,stdout = s.PIPE) print 'pOpen done..' while: line = ps.stdout.readline() print line
手动打开时,它比原始exe文件少打印两行。
我尝试了一种具有相同结果的替代方法:
f = open('myprogram_output.txt','w') proc = Popen('C:\Tools\Dvb_pid_3_0.exe ', stdout =f) line = proc.stdout.readline() print line f.close()
任何人都可以帮助我获取exe的完整数据吗?
原始exe文件最后几行o / p:
-Gdd:通用计数(1-1000)
-Cdd:切割起始于(0-99)-Edd:切割终止于(1-100)
请在下面选择流文件编号:
1-。\ pdsx100-bcm7230-squashfs-sdk0.0.0.38-0.2.6.0-prod.sao.ts
运行后得到的输出:
-P0xYYYY : Pid been interested
-S0xYYYY:对服务ID感兴趣 -T0xYYYY:对传输ID感兴趣 -N0xYYYY:对网络ID感兴趣 -R0xYYYY:该PID替换了旧的Pid -Gdd:通用计数(1-1000)
因此,我们可以看到缺少一些行。我必须写1并选择值,请选择以下显示的文件编号。
我尝试使用ps.stdin.write(‘1 \ n’)。它没有在exe文件中打印值
新代码:
#!/usr/bin/env python from subprocess import Popen, PIPE cmd = r'C:\Tools\Dvb_pid_3_0.exe' p = Popen(cmd, stdin=PIPE, stdout=None, stderr=None, universal_newlines=True) stdout_text, stderr_text = p.communicate(input="1\n\n") print("stdout: %r\nstderr: %r" % (stdout_text, stderr_text)) if p.returncode != 0: raise RuntimeError("%r failed, status code %d" % (cmd, p.returncode))
谢谢塞巴斯蒂安。我能够看到整个输出,但无法使用当前代码输入任何输入。
要将所有标准输出作为字符串获取:
from subprocess import check_output as qx cmd = r'C:\Tools\Dvb_pid_3_0.exe' output = qx(cmd)
要将stdout和stderr都作为单个字符串获取:
from subprocess import STDOUT output = qx(cmd, stderr=STDOUT)
要将所有行作为列表:
lines = output.splitlines()
要获得子进程正在打印的行,请执行以下操作:
from subprocess import Popen, PIPE p = Popen(cmd, stdout=PIPE, bufsize=1) for line in iter(p.stdout.readline, ''): print line, p.stdout.close() if p.wait() != 0: raise RuntimeError("%r failed, exit status: %d" % (cmd, p.returncode))
添加stderr=STDOUT到Popen()合并stdout / stderr的调用中。
stderr=STDOUT
Popen()
注意:如果cmd在非交互模式下使用块缓冲,则直到缓冲区刷新后才会出现行。winpexpect模块可能能够更快地获取输出。
cmd
winpexpect
要将输出保存到文件:
import subprocess with open('output.txt', 'wb') as f: subprocess.check_call(cmd, stdout=f) # to read line by line with open('output.txt') as f: for line in f: print line,
如果cmd总是要求输入,即使是空的;设置stdin:
stdin
import os with open(os.devnull, 'rb') as DEVNULL: output = qx(cmd, stdin=DEVNULL) # use subprocess.DEVNULL on Python 3.3+
您可以结合使用以下解决方案,例如,合并stdout / stderr并将输出保存到文件中,并提供空输入:
import os from subprocess import STDOUT, check_call as x with open(os.devnull, 'rb') as DEVNULL, open('output.txt', 'wb') as f: x(cmd, stdin=DEVNULL, stdout=f, stderr=STDOUT)
要将所有输入作为单个字符串提供,您可以使用.communicate()方法:
.communicate()
#!/usr/bin/env python from subprocess import Popen, PIPE cmd = ["python", "test.py"] p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, universal_newlines=True) stdout_text, stderr_text = p.communicate(input="1\n\n") print("stdout: %r\nstderr: %r" % (stdout_text, stderr_text)) if p.returncode != 0: raise RuntimeError("%r failed, status code %d" % (cmd, p.returncode))
在哪里test.py:
test.py
print raw_input('abc')[::-1] raw_input('press enter to exit')
如果您与程序的交互更像是对话,而不需要winpexpect模块。这是docs的示例pexpect:
pexpect
# This connects to the openbsd ftp site and # downloads the recursive directory listing. from winpexpect import winspawn as spawn child = spawn ('ftp ftp.openbsd.org') child.expect ('Name .*: ') child.sendline ('anonymous') child.expect ('Password:') child.sendline ('noah@example.com') child.expect ('ftp> ') child.sendline ('cd pub') child.expect('ftp> ') child.sendline ('get ls-lR.gz') child.expect('ftp> ') child.sendline ('bye')
要发送特殊密钥,例如F3,F10在Windows上,您可能需要SendKeys模块或其纯Python实现SendKeys- ctypes。就像是:
F3
F10
SendKeys
SendKeys- ctypes
from SendKeys import SendKeys SendKeys(r""" {LWIN} {PAUSE .25} r C:\Tools\Dvb_pid_3_0.exe{ENTER} {PAUSE 1} 1{ENTER} {PAUSE 1} 2{ENTER} {PAUSE 1} {F3} {PAUSE 1} {F10} """)
它不捕获输出。