【问题标题】:Prevent subprocess PIPE from blocking防止子进程 PIPE 阻塞
【发布时间】:2023-03-11 19:15:01
【问题描述】:

我想利用子进程Popen 在 Linux 上调用 strace。 如果可能,我还想实时捕获 strace 给出的每一行输出。

为此我想出了以下代码,但由于某种原因,我无法让它工作。我只会在终止程序后得到输出。

from threading import Thread
from queue import Queue, Empty

pid = 1

def enqueue_output(out, queue):
    for line in iter(out.readline, b''):
        queue.put(line)
    out.close()

p = Popen(["strace", "-p", pid], stdout=subprocess.PIPE, bufsize=1)
q = Queue()
t = Thread(target=enqueue_output, args=(p.stdout, q))
t.daemon = True # thread dies with the program
t.start()

try:
    line = q.get_nowait()
    print("Got it! "+line)
except Empty:
    pass

【问题讨论】:

  • 安装信号不是更好吗,比如stackoverflow.com/questions/132058/…
  • 嗨!我不想跟踪 Python 程序,所以安装信号没有用,不是吗?
  • 队列的预期目的是什么?您可以直接从子流程输出中读取。
  • 队列旨在从单独的线程读取输出作为一种缓冲区。我也试过不排队,但也没有用。

标签: python multithreading subprocess pipe strace


【解决方案1】:

这是一个简短的工作示例:

请注意:

  • strace 写信给stderr(除非给出-o filename
  • 所有参数必须是字符串(或字节),即 pid 必须为“1”
  • 行缓冲仅适用于通用换行符
  • 您必须是 root 才能跟踪进程 1

import subprocess

PID = 1 

p = subprocess.Popen(
    ["strace", "-p", str(PID)],
    stdin=subprocess.DEVNULL, stderr=subprocess.PIPE,
    universal_newlines=True, bufsize=1)
for line in p.stderr:
    line = line.rstrip()
    print(line)

【讨论】:

  • 像魅力一样工作!非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-22
  • 1970-01-01
  • 2016-11-29
  • 1970-01-01
  • 2014-03-23
  • 2015-04-22
  • 2016-10-26
相关资源
最近更新 更多