如何使用子进程和Popen从.exe中获取所有输出?

发布于 2021-01-29 19:34:05

我正在尝试运行可执行文件并使用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))

谢谢塞巴斯蒂安。我能够看到整个输出,但无法使用当前代码输入任何输入。

关注者
0
被浏览
59
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    要将所有标准输出作为字符串获取:

    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=STDOUTPopen()合并stdout / stderr的调用中。

    注意:如果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

    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()方法:

    #!/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模块。这是docs示例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')
    

    要发送特殊密钥,例如F3F10在Windows上,您可能需要SendKeys模块或其纯Python实现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}
    """)
    

    它不捕获输出。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看