【问题标题】:Get the stdout/stderr of a forked process in a subprocess在子进程中获取分叉进程的 stdout/stderr
【发布时间】:2025-12-07 17:35:01
【问题描述】:

我有一个调用fork()的C程序

我有一个 python 脚本,它执行 C 程序

child = subprocess.Popen(command, shell=True, stderr=subprocess.PIPE,stdout=subprocess.PIPE, bufsize=0)

现在我可以使用 child.stderr.read(1)child.communicate()stdoutstderr 读取,...但是我现在的问题是,我怎样才能得到 forked 进程的输出。这甚至可能吗?我可以从原始 C 程序和 fork 中获取 pid 吗?

亲切的问候, 非常感谢:)

法比安

【问题讨论】:

  • “这可能吗?”不。“我可以从原始 C 程序和 fork 两者中获取 pid 吗?”不,C 程序拥有那个孩子。您的进程拥有 C 程序。现在。停止担心 Linux 细节并描述您的真正问题。为什么你的 Python 程序不能和 C 程序运行相同的子进程?
  • 一种更简单的方法可能是使用不同的输出格式,主进程可以从:“ParentOutput:”开始,而子进程的输出是:“ChildOutput:”。然后你可以在你的python程序中忽略“ParentOutput”。

标签: python fork subprocess stdout stderr


【解决方案1】:

您所要求的将是复杂的,并且在纯 python 中是不可能的——您需要一些特定于操作系统的机制。

你真的要求两件事:

  • 根据父进程的 PID 识别分叉进程
  • 拦截任意进程的标准输入/输出

如果您在 Linux 上,您可能可以通过解析 /proc 来完成前者,后者实际上是一个类似于调试器的功能(例如 How can a process intercept stdout and stderr of another process on Linux?

您更有可能想要更改 C 程序的工作方式——例如,从 python 脚本而不是中间 C 代码执行 fork()/daemonization 可以让您直接获取子进程。

【讨论】:

    【解决方案2】:

    我认为当你在 C 中 fork() 一个进程时,你不能将任何描述符从子进程传递回父进程 - 但可能我错了。只有你得到的是新子进程的PID。最好的方法应该是打开一个管道(使用常规名称,例如管道名称包含进程的 PID),然后您可以从任何地方打开它。

    最后,当你 fork() 进程时,它会为你提供 PID,你可以将 PID(C 二进制和分叉)写入 C 程序的标准输出,例如使用分隔符:

    cpid = fork();
    printf("%d|%d", (int)get_pid(), cpid);
    

    祝你好运:)

    【讨论】: