首页 > 解决方案 > 键盘中断后获取子进程的输出

问题描述

我想在用户执行键盘中断后将子进程的最后一个输出存储到一个变量中。我的问题主要是没有结束的子流程,即下面我的示例中的尾部。这是我的代码:

class Testclass:
    def Testdef(self):
        try:
            global out
            print "Tail running"
            tail_cmd='tail -f log.Reconnaissance'
            proc = subprocess.Popen([tail_cmd], stdout=subprocess.PIPE, shell=True)
            (out, err) = proc.communicate()
        except KeyboardInterrupt:
            print("KeyboardInterrupt received, stopping…")
        finally:
            print "program output:", out

if __name__ == "__main__":
    app = Testclass()
    app.Testdef()

下面是它的输出,我现在不明白。

Tail running
program output:
Traceback (most recent call last):
  File "./2Test.py", line 19, in <module>
    app.Testdef()
  File "./2Test.py", line 15, in Testdef
    print "program output:", out
NameError: global name 'out' is not defined

标签: pythonsubprocess

解决方案


out未定义表示该进程proc.communicate()未返回任何值,否则它将填充您的 tuple (out, err)。现在要确定该communicate()方法是否应该返回,或者更可能的是,您的键盘中断是否简单地杀死了它,从而防止out被定义。


我假设您导入了subprocess模块,但请确保您先执行此操作。global out我在没有使用ortry语句的情况下重写了您的程序。

import subprocess
class Testclass:
    def __init__(self,out):    # allows you to pass in the value of out
        self.out = out    # makes out a member of this class
    def Testdef(self):
        print("Tail running")
        tail_cmd='tail -f log.Reconnaissance'
        proc = subprocess.Popen([tail_cmd], stdout=subprocess.PIPE, shell=True)
        # Perhaps this is where you want to implement the try:
        (self.out, err) = proc.communicate()
        # and here the except:
        # and here the finally:

if __name__ == "__main__":
    app = Testclass(1)    # pass 1 (or anything for testing) to the out variable
    app.Testdef()
    print('%r' % app.out) # print the contents of the out variable
                          # i get an empty string, ''

所以这个程序运行一次。里面什么都没有out。我相信要创建一个有意义的用户做键盘中断的例子,我们需要程序做一些可以被中断的事情。也许我可以在未来提供一个例子......


推荐阅读