【问题标题】:printing results in stdout file as well as console在标准输出文件和控制台中打印结果
【发布时间】:2013-07-06 11:45:40
【问题描述】:

我的要求是在控制台中打印文件的输出以及日志文件。以下代码为我做了这件事,除了一个小问题。我在文件末尾调用了一个 perl 脚本,其输出显示在控制台中,但没有打印到文件中。

import subprocess
import sys
class Tee(object):
    def __init__(self, *files):
        self.files = files
    def write(self, obj):
        for f in self.files:
            f.write(obj)

f = open('MyFile.txt', 'w')
original = sys.stdout
sys.stdout = Tee(sys.stdout, f)
print "Logging Started"
# My code
print "A"

subprocess.call(['./MyScript])
sys.stdout = original
print "Logging Stopped"  # Only on stdout
f.close()

谁能告诉我如何实现?或者有没有可能达到同样的效果?

【问题讨论】:

    标签: python logging printing python-2.6


    【解决方案1】:

    下面的代码对我有用。感谢大家的帮助。

    #!/usr/bin/python
    import os
    import subprocess
    import sys
    class Tee(object):
        def __init__(self, *files):
            self.files = files
        def write(self, obj):
            for f in self.files:
                f.write(obj)
    
    f = open('MyFile.txt', 'w')
    original = sys.stdout
    sys.stdout = Tee(sys.stdout, f)
    print "Logging Started"
    # My code
    print "A"
    
    def check_output(*popenargs, **kwargs):
        process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
        output, unused_err = process.communicate()
        retcode = process.poll()
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
            error = subprocess.CalledProcessError(retcode, cmd)
            error.output = output
            raise error
        return output
    
    location = "%s/folder"%(os.environ["Home"])
    myoutput = check_output(['./MyFile'])
    print myoutput
    sys.stdout = original
    print "Logging Stopped"  # Only on stdout
    f.close()
    

    【讨论】:

      【解决方案2】:

      使用subprocess.check_output:

      print subprocess.check_output(['./MyScript])
      

      在 Python 2.6 中,使用反向端口 subprocess32,或复制 2.7 source for check_output

      【讨论】:

      • print subprocess.check_output(['./MyScript']) AttributeError: 'module' object has no attribute 'check_output'
      • Python 2.6.4,很抱歉造成混淆。将删除标签。
      • @misguided,如果您单击文档的链接,您可以看到它是在 Python 2.7 中添加的,这就是您标记问题的内容
      • 如果您不在 2.7 上,请使用 subprocess32 反向端口(顾名思义,它还为您提供了 3.2 对 communicate 的改进,等等……虽然不是 3.3 的改进,当然)。
      【解决方案3】:

      如果你看check_output是在Python2.7中实现的,你应该就能知道如何使用subprocess.Popen

      def check_output(*popenargs, **kwargs):
          if 'stdout' in kwargs:
              raise ValueError('stdout argument not allowed, it will be overridden.')
          process = Popen(stdout=PIPE, *popenargs, **kwargs)
          output, unused_err = process.communicate()
          retcode = process.poll()
          if retcode:
              cmd = kwargs.get("args")
              if cmd is None:
                  cmd = popenargs[0]
              raise CalledProcessError(retcode, cmd, output=output)
          return output
      

      【讨论】:

        【解决方案4】:
        subprocess.check_ouput
        

        在python 2.7中引入,如果你可以使用以前的版本,你可以使用Popen并将stdout设置为你的输出流(但在你的情况下,你已经覆盖了sys.stdout,我认为它不需要),只需更改为:

        p = subprocess.Popen(['./MyScript'])
        

        【讨论】:

        • 不提供所需的输出。在运行MyScript 后,我正在运行脚本的 unix (SSH) 窗口也会挂起
        • 这不是一个完整的解决方案;仅仅创建一个Popen 没有任何好处,除非你也将它传递给stdout 管道,从中读取,然后pollwait 进程(或将后两者合并到communicate)。
        • @abarnert 你的意思是session = subprocess.Popen(['./MyScript'], stdin=PIPE, stdout=PIPE, stderr=PIPE)。虽然不知道从这里做什么
        • @misguided:我不会管stdinstderr;这只会让它变得更复杂。无论如何,您从那里所做的是……确切地说,Ashwini 的答案和我的评论链接到 check_output 的源代码中的内容,并且该 gnibbler 的答案直接复制:output, _ = p.communicate(); ret = p.poll(); if ret: raise soemthing
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-10
        相关资源
        最近更新 更多