【问题标题】:Python execv and pipe outputPython execv 和管道输出
【发布时间】:2017-10-19 22:22:48
【问题描述】:

我想使用 Python 的 os.execv 替换我当前的进程,但我也希望新进程将 stdout 发送到另一个进程(收集日志并通过网络发送它们)。收集日志的进程也需要由原Python进程启动。

我猜我需要做一些 fork、dup2、execv 的事情,但我需要一些帮助。

在 bash 中,它可能看起来像这样

#!/bin/bash
exec ./foo ∣ ./bar

【问题讨论】:

  • subprocess 模块可以为您执行此操作:gist.github.com/JacobIRR/dced5ce0f19e4f376aaef19d0e80d9d7
  • @JacobIRR 在子进程中运行命令,它不会替换当前进程。
  • 次要注意,这并不完全符合您在 Bash 中的想法 - 主进程遵循管道的最后阶段,因此 exec 无效。
  • @ephemient 感谢您的澄清。我想这意味着我不确定如何在 Python 和 Bash 中做到这一点!
  • Bash 中最接近的类似物是进程替换,例如 exec ./foo > >(./bar)

标签: python process pipe fork exec


【解决方案1】:

您可以通过这种方式设置管道和进程。

import os

(read_fd, write_fd) = os.pipe()
pid = os.fork()
if pid == 0:
    os.dup2(read_fd, 0)
    os.close(read_fd)
    os.close(write_fd)
    os.execlp('./bar', './bar')
    os._exit(-1)  # in case exec fails
os.close(read_fd)
os.dup2(write_fd, 1)
os.close(write_fd)
os.execlp('./foo', './foo')

不过,使用subprocess 仍然很方便,至少在第一部分是这样。

import os
import subprocess

p = subprocess.Popen(['./bar'], stdin=subprocess.PIPE)
os.dup2(p.stdin.fileno(), 1)
p.stdin.close()
os.execlp('./foo', './foo')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-15
    • 1970-01-01
    相关资源
    最近更新 更多