1

我正在为 Debian 的 debootstrap 实用程序编写一个 python 前端。Debootstrap 可以输出进度信息,但如果文件描述符#3 打开,它就会输出进度信息,并且它会写入这个 fd

我找到了一些提示,但我不明白如何在 Python 中做到这一点。

如何在 Python 中创建 fd#3、运行 debootstrap 子进程并从 fd#3 中读取?

4

2 回答 2

2

我认为您需要使用低级操作系统 API 在 fd 3 上设置管道,例如:

import os, sys

# No other fds have been opened, so the lowest available are used (3, 4)
read, write = os.pipe()

# We want the child to write into fd#3, but right now that's the read
# end of the pipe, so do a little switching around:
temp = os.dup(read)
os.dup2(write, read)
os.dup2(temp, write)
os.close(temp)
read, write = write, read # swap actual values to avoid confusion

pid = os.fork()
if pid == 0: # child
   os.close(read)
   try:
       os.execl('/bin/bash', 'bash', '-c', 'echo testing...>&3')
   except OSError:
       sys.exit(1)
else: # parent
   os.close(write)
   progress = os.fdopen(read)
   print progress.read()
   os.wait()

基本上,创建管道,并交换读/写端,以便写端位于 fd#3 上(将使用最低的可用 fd,因此请确保您尚未打开任何其他 fd)。

然后,分叉并关闭父子节点中适当的管道末端。然后我们可以在孩子中执行目标,在我bash的例子中。然后,在父级中,我们可以在管道的读取端构建一个普通的类似文件的对象,并继续处理它,而不用担心低级 API。

如果您在管道的读取端设置,则可能可以使用该subprocess模块FD_CLOEXEC,但您仍然需要进行低级调用来设置管道,因此这样做没有太大的收获。

于 2013-04-09T19:49:17.300 回答
0

这里是:

import os, sys

read, write = os.pipe()

pid = os.fork()
if pid == 0: # child
   os.close(read)
   os.dup2(write, 3)
   os.close(write)
   try:
       os.execl('/bin/bash', 'bash', '-c', 'for f in 1 2 3 4 5 6 7 8; do echo testing...>&3; sleep 1; done')
   except OSError:
       sys.exit(1)
else: # parent
   os.close(write)
   progress = os.fdopen(read)
   while True:
       l = progress.readline()
       if l:
           print l
       else:
           break
于 2013-04-10T11:30:07.363 回答