当前位置: 首页 > 面试题库 >

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

法子昂
2023-03-14
问题内容

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

它不捕获输出。



 类似资料:
  • 我有一个EXE文件,< code>addOne.exe,它不断地从控制台上的用户获得一个整数输入(不是命令行参数),并将整数1输出到控制台上。示例输出如下所示: 我正在尝试编写一个java程序,它可以: 运行 EXE 使用 从 Java 程序持续获取用户输入,并将输入到 EXE 作为控制台输入 每当 EXE 将文本输出到控制台时,请从 Java 程序打印该文本 我可以使用以下方式运行EXE: 但我

  • 问题内容: 是否可以从Shell脚本中的父进程ID获取子进程ID? 我有一个要使用Shell脚本执行的文件,这会导致一个新进程 process1 (父进程)。这个 过程1 已经分叉的另一个进程 过程2 (子进程)。使用脚本,我可以使用以下命令获取 process1 的pid : 但我无法获取子进程的pid。 问题答案: 只需使用:

  • 是否可以从外壳脚本中的父进程ID获取子进程ID? 我有一个要使用shell脚本执行的文件,这会导致一个新的进程process1(父进程)。此进程1已经派生了另一个进程process2(子进程)。使用脚本,我可以使用以下命令获得进程1的pid: 但是我无法获取子进程的pid。

  • 问题内容: 我正在做一个漂亮的小功能: 问题是那不是正确的PID。似乎总是比正确的PID低1。例如,它说该进程始于31729,但是说它正在31730运行。每次我尝试将其关闭1。我猜它返回的PID是 当前 进程的PID ,而不是启动的PID ,并且新进程获得的“下一个” pid为高1。在这种情况下,我不能仅仅依靠返回值,因为我不能保证它总是正确的。 为什么不返回新流程的PID,如何实现所追求的行为?

  • 问题内容: 我试图弄清楚如何从用CreateProcessW创建的过程中读取标准输出/错误。我看了看文档,用谷歌搜索了这个列表,但是我还没有找到好的指针/样本:) 到目前为止,这是我想到的(在Windows上运行良好,这是我的Java代码中的相关代码段): 那么…我该如何获取该过程的输出?任何人都已经做到了,并愿意分享一个样本吗? 谢谢大家的任何帮助。 问题答案: 为了向使用功能创建的进程写入控制

  • 我有一个启动ChromeDrivers的程序,它启动Chrome浏览器,然后在完成一些任务(使用Selenium)后尝试关闭这两个浏览器。但我的程序经常无法关闭ChromeDriver/Chrome浏览器。当我试图关闭ChromeDriver时,Chrome浏览器的所有其他子进程都没有关闭。 我试图查看/proc/x/environ以确定是否可以提取进程的显示,但发现没有为浏览器子进程设置这样的环