如何从Python脚本捕获Python解释器和/或CMD.EXE输出?

时间:2008-08-24 08:46:57

标签: python windows cmd

  1. 是否可以从Python脚本中捕获Python解释器的输出?
  2. 是否可以从Python脚本中捕获Windows CMD的输出?
  3. 如果是这样,我应该查看哪个图书馆(y | ies)?

5 个答案:

答案 0 :(得分:9)

如果您正在谈论python解释器或CMD.exe,它是您脚本的“父”,那么不可能。在每个类似POSIX的系统中(现在你正在运行Windows,看起来可能有一些我不知道的怪癖,YMMV)每个进程都有三个流,标准输入,标准输出和标准错误。 Bu默认(在控制台中运行时)这些指向控制台,但可以使用管道符号进行重定向:

python script_a.py | python script_b.py

这将脚本a的标准输出流与脚本B的标准输入流联系起来。在此示例中,标准错误仍然发送到控制台。请参阅维基百科上standard streams上的文章。

如果你正在谈论一个子进程,你可以像这样从python启动它(如果你想进行双向通信,stdin也是一个选项):

import subprocess
# Of course you can open things other than python here :)
process = subprocess.Popen(["python", "main.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
x = process.stderr.readline()
y = process.stdout.readline()
process.wait()

有关管理流程的信息,请参阅Python subprocess模块。对于通信,process.stdin和process.stdout管道被视为标准file objects

对于管道使用,从标准输入读取lassevk建议您执行以下操作:

import sys
x = sys.stderr.readline()
y = sys.stdin.readline()

sys.stdin和sys.stdout是上面提到的标准文件对象,在sys模块中定义。您可能还想查看pipes模块。

在我的示例中使用readline()读取数据是获取数据的一种非常天真的方式。如果输出不是面向行或不确定的,你可能想要查看polling,遗憾的是它在Windows中不起作用,但我确信那里有一些替代方案。

答案 1 :(得分:5)

我想我可以为你问题的第一部分指出一个好的答案。

  

1。是否可以从Python捕获Python解释器的输出   脚本?

答案是“”,我个人非常喜欢 PEP 343 -- The "with" Statement 文档中的示例中的以下内容。

from contextlib import contextmanager
import sys

@contextmanager
def stdout_redirected(new_stdout):
    saved_stdout = sys.stdout
    sys.stdout = new_stdout
    try:
        yield None
    finally:
        sys.stdout.close()
        sys.stdout = saved_stdout

并像这样使用:

with stdout_redirected(open("filename.txt", "w")):
    print "Hello world"

它的一个很好的方面是它可以选择性地应用于脚本执行的一部分,而不是整个范围,并且即使在其上下文中引发未处理的异常也会保持有效。如果您在首次使用后以附加模式重新打开该文件,则可以将结果累积到一个文件中:

with stdout_redirected(open("filename.txt", "w")):
    print "Hello world"

print "screen only output again"

with stdout_redirected(open("filename.txt", "a")):
    print "Hello world2"

当然,上述内容也可以扩展为将sys.stderr重定向到相同或另一个文件。另请参阅此answer相关问题。

答案 2 :(得分:3)

实际上,你绝对可以,同时又美丽,丑陋,疯狂!

您可以使用收集输出的StringIO对象替换sys.stdout和sys.stderr。

这是一个示例,将其另存为evil.py:

import sys
import StringIO

s = StringIO.StringIO()

sys.stdout = s

print "hey, this isn't going to stdout at all!"
print "where is it ?"

sys.stderr.write('It actually went to a StringIO object, I will show you now:\n')
sys.stderr.write(s.getvalue())

运行此程序时,您将看到:

  • 没有去stdout(打印通常打印到的地方)
  • 写入stderr的第一个字符串是以'It'
  • 开头的字符串
  • 接下来的两行是在StringIO对象中收集的行

像这样替换sys.stdout / err是一个叫做monkeypatching的应用程序。意见可能会有所不同,无论这是否“支持”,这绝对是一个丑陋的黑客,但它在尝试包裹外部东西一次或两次时保存了我的培根。

在Linux上测试,而不是在Windows上测试,但它也应该可以正常工作。如果它适用于Windows,请告诉我!

答案 3 :(得分:1)

你想要subprocess。请特别注意17.1.1中的Popen,并在17.1.2中进行沟通。

答案 4 :(得分:0)

你在问哪个环境?

您是否尝试捕获从命令行启动的程序的输出?

如果是的话,那就是如何执行它:

somescript.py | your-capture-program-here

并读取输出,只需从标准输入读取。

另一方面,如果您正在程序中执行该脚本或cmd.exe或类似程序,并希望等到脚本/程序完成并捕获其所有输出,那么您需要查看在库中调用你用来启动那个外部程序,很可能有一种方法可以让它给你一些方法来读取输出并等待完成。