发送SIGINT后从子进程捕获stdout

时间:2014-08-26 07:06:46

标签: python

我有一个通过python脚本运行的dtrace片段,并且dtrace片段是这样的,当它发出CTRL-C时它会生成数据。所以我在python脚本中定义了一个signal_handler来捕获用户的CTRL-C并将其转发到通过subprocess.Popen完成的dtrace调用,但是我无法在我的日志文件中获得任何输出。这是脚本:

Proc = []
signal_posted = False

def signal_handler(sig, frame):
    print("Got CTRL-C!")
    global signal_posted
    signal_posted = True
    global Proc
    Proc.send_signal(signal.SIGINT) #Signal posting from handler

def execute_hotkernel():
    #
    # Generate the .out output file
    #
    fileout = "hotkernel.out"
    fileo = open(fileout, "w+")

    global Proc
    Proc = subprocess.Popen(['/usr/sbin/dtrace', '-n', dtrace_script], stdout = fileo)
    while Proc.poll() is None:
        time.sleep(0.5)

def main():
    signal.signal(signal.SIGINT, signal_handler)        # Change our signal handler
    execute_hotkernel()

if __name__ == '__main__':
    main()

由于我在stdout的subprocess.Popen命令中设置了文件hotkernel.out,我希望dtrace的输出在执行CTRL-C时被重定向到hotkernel.out但它是空的。这里缺少什么?

1 个答案:

答案 0 :(得分:1)

我有类似的问题。

就我而言,它是一个shell脚本,一直运行直到你点击Control-C,然后打印出摘要信息。当我使用subprocess.Popen运行它时,无论是使用PIPE还是stdout的文件对象,我要么不获取信息(带有文件对象),要么在我尝试运行stdout.readline()时挂起。

我终于尝试从解释器运行子进程并发现如果我调用stdout.readline()(它挂起)并点击Control-C(在解释器中),我可以在带有PIPE的SIGINT之后得到最后一行输出),然后再次调用stdout.readline()。

我不知道如何在脚本,文件输出或PIPE中模拟这个。我没有在解释器中尝试文件输出。

编辑: 我终于回到了这个并确定,它实际上很容易在python之外模拟,并且与python无关。

/some_cmd_that_ends_on_sigint
(enter control-c)
*data from stdout in event handler*

作品

/some_cmd_that_ends_on_sigint | tee some.log
(enter control-c)
*Nothing sent to stdout in event handler prints to the screen or the log*

我的日志在哪里?

我最后只是在事件处理程序(在some_cmd_that_ends_on_sigint源中)中添加了一个文件流,该文件流将数据写入(可能是次要的)日志。工作,如果有点尴尬。如果在没有任何管道的情况下运行,你可以在屏幕上获得数据,但我也可以在管道或从辅助日志中的python中读取它。