【问题标题】:How to pipe to stdin of os.execv'd process in Python如何在 Python 中通过管道传输到 os.execv 进程的标准输入
【发布时间】:2014-07-10 18:48:02
【问题描述】:

我想写一些东西到一个进程的标准输入 替换我当前的 Python 进程。是否有捷径可寻?我的思路是

import sys, os

r, w = os.pipe()
os.write(w, 'yo')
os.dup2(r, sys.stdin.fileno())
os.execvp('cat', [''])

但是当我在 OS X 中执行此操作时,cat 挂起,尽管确实显示了“yo”。为什么?

【问题讨论】:

  • 这样的代码很危险——如果你将多个管道缓冲区的数据写入管道(其大小因操作系统等而异),那么你将死锁你的进程,因为没有读者还没有排干管道。
  • 那我怎样才能以一种安全的方式做我想做的事——不写一个临时文件呢?
  • os.fork()之前的进程execvp()-ing子进程;然后,父级写入管道,而子级从管道中读取。父级还必须在fork() 之后close() 管道的读取端,子级必须将读取端dup2()stdin 上,然后在execvp() 之前关闭两个原始管道句柄。这是非常标准的 Unix 管道。
  • 亚当,如果你还想写你的评论作为答案,我会选择它。从你写的东西和我自己的错误中吸取教训。

标签: python operating-system


【解决方案1】:

os.fork()之前的进程execvp()-ing子进程;然后,父级写入管道,而子级从管道中读取。父级还必须在fork() 之后close() 管道的读取端,子级必须将读取端dup2()stdin 上,然后在execvp() 之前关闭两个原始管道句柄。这是非常标准的 Unix 管道。

例如:

r, w = os.pipe()
if os.fork() == 0:
    # Child process
    os.dup2(r, sys.stdin.fileno())
    os.close(r)
    os.close(w)
    os.execvp(...)
else:
    # Parent process
    os.close(r)
    os.write(w, 'yo')
    ...
    os.close(w)  # When done writing
    os.wait()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-03
    • 1970-01-01
    • 2022-07-05
    • 2013-06-25
    相关资源
    最近更新 更多