如何使用子进程和Popen从.exe中获取所有输出? [英] How do I get all of the output from my .exe using subprocess and Popen?
问题描述
我试图运行一个可执行文件并使用subprocess.Popen
捕获其输出;但是,我似乎并没有获得全部输出.
I am trying to run an executable and capture its output using subprocess.Popen
; however, I don't seem to be getting all of the output.
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文件少打印两行.
It prints two line less than the original exe file when opened manually.
我尝试了一种具有相同结果的替代方法:
I tried an alternative approach with the same result:
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的完整数据吗?
Can anyone please help me to get the full data of the exe?
原始exe文件最后几行o/p:
Original exe file last few lines o/p:
-Gdd:通用计数(1-1000)
-Gdd : Generic count (1 - 1000)
-Cdd:切割开始于(0-99) -Edd:切割结束于(1-100)
-Cdd : Cut start at (0 - 99) -Edd : Cut end at (1 - 100)
请在下面选择流文件编号:
Please select the stream file number below:
1-.\ pdsx100-bcm7230-squashfs-sdk0.0.0.38-0.2.6.0-prod.sao.ts
1 - .\pdsx100-bcm7230-squashfs-sdk0.0.0.38-0.2.6.0-prod.sao.ts
跑步后得到的o/p:
-P0xYYYY : Pid been interested
-S0xYYYY:对服务ID感兴趣
-T0xYYYY:传输ID感兴趣
-N0xYYYY:对网络ID感兴趣
-R0xYYYY:一个旧的Pid已被此PID替换
-Gdd:通用计数(1-1000)
-S0xYYYY : Service ID been interested
-T0xYYYY : Transport ID been interested
-N0xYYYY : Network ID been interested
-R0xYYYY : A old Pid been replaced by this PID
-Gdd : Generic count (1 - 1000)
所以我们可以看到缺少的几行.我必须写1并选择值,请选择下面的文件编号.
So we can see some lines missing. I have to write 1 and choose value after please select the fule number below appears.
我尝试使用ps.stdin.write('1 \ n').它没有在exe文件中打印该值
I tried to use ps.stdin.write('1\n'). It didn't print the value in the exe file
新代码:
#!/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))
感谢塞巴斯蒂安.我能够看到整个输出,但无法用当前代码输入任何输入.
Thanks Sebastien. I am able to see the entire output but not able to feed in any input with the current code.
推荐答案
以字符串形式获取所有标准输出:
To get all stdout as a string:
from subprocess import check_output as qx
cmd = r'C:\Tools\Dvb_pid_3_0.exe'
output = qx(cmd)
要将stdout和stderr都作为单个字符串获取:
To get both stdout and stderr as a single string:
from subprocess import STDOUT
output = qx(cmd, stderr=STDOUT)
要获得所有行的列表:
lines = output.splitlines()
要获得子进程正在打印的行,请执行以下操作:
To get lines as they are being printed by the subprocess:
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))
在Popen()
调用中添加stderr=STDOUT
以合并stdout/stderr.
Add stderr=STDOUT
to the Popen()
call to merge stdout/stderr.
注意:如果cmd
在非交互模式下使用块缓冲,则直到缓冲区刷新后才会出现行. winpexpect
模块可能能够更快地获取输出.
Note: if cmd
uses block-buffering in the non-interactive mode then lines won't appear until the buffer flushes. winpexpect
module might be able to get the output sooner.
要将输出保存到文件中:
To save the output to a file:
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
:
If cmd
always requires input even an empty one; set stdin
:
import os
with open(os.devnull, 'rb') as DEVNULL:
output = qx(cmd, stdin=DEVNULL) # use subprocess.DEVNULL on Python 3.3+
您可以结合使用这些解决方案,例如,合并stdout/stderr,并将输出保存到文件中,并提供空的输入:
You could combine these solutions e.g., to merge stdout/stderr, and to save the output to a file, and to provide an empty input:
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()
方法:
To provide all input as a single string you could use .communicate()
method:
#!/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
:
print raw_input('abc')[::-1]
raw_input('press enter to exit')
如果与程序的交互更像是对话,则可能不需要 winpexpect
模块.这是来自pexpect
文档的的示例.
If your interaction with the program is more like a conversation than you might need winpexpect
module. Here's an example from pexpect
docs:
# 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')
要在Windows上发送诸如F3
,F10
之类的特殊键,您可能需要 SendKeys
模块或其纯Python实现 SendKeys-ctypes
.像这样:
To send special keys such as F3
, F10
on Windows you might need SendKeys
module or its pure Python implementation SendKeys-ctypes
. Something like:
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}
""")
它不捕获输出.
这篇关于如何使用子进程和Popen从.exe中获取所有输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!