使用文件描述符在进程之间进行通信

时间:2010-09-22 12:11:56

标签: python ipc zsh file-descriptor

我有以下python代码:

import pty
import subprocess
os=subprocess.os
from subprocess import PIPE
import time
import resource

pipe=subprocess.Popen(["cat"], stdin=PIPE, stdout=PIPE, stderr=PIPE, \
                      close_fds=True)
skip=[f.fileno() for f in (pipe.stdin, pipe.stdout, pipe.stderr)]
pid, child_fd = pty.fork()
if(pid==0):
    max_fd=resource.getrlimit(resource.RLIMIT_NOFILE)[0]
    fd=3
    while fd<max_fd:
        if(fd not in skip):
            try:
                os.close(fd)
            except OSError:
                pass
            fd+=1
        enviroment=os.environ.copy()
        enviroment.update({"FD": str(pipe.stdin.fileno())})
        os.execvpe("zsh", ["-i", "-s"], enviroment)
else:
    os.write(child_fd, "echo a >&$FD\n")
    time.sleep(1)
    print pipe.stdout.read(2)

如何重写它以便它不会使用Popencat?我需要一种从交互式shell中运行的shell函数传递数据的方法,该函数不会与其他函数创建的数据混合(因此我不能使用stdout或stderr)。

1 个答案:

答案 0 :(得分:1)

好的,我想我现在已经掌握了你的问题,看看你可以采取两种不同的方法。

如果您绝对想要在子进程中为已打开的文件描述符提供shell,那么您可以通过调用Popen()来替换cat os.pipe()。这将为您提供一对连接的真实文件描述符(不是Python file对象)。写入第二个文件描述符的任何东西都可以从第一个文件描述符中读取,替换你的陪审团操纵的cat - 管道。 (虽然“cat-pipe”很有趣但是......)。如果您需要双向对,也可以使用套接字对(socket.socketpair())来实现相同的目的。

或者,您可以使用命名管道(即FIFO)进一步简化您的生活。如果您不熟悉该工具,则命名管道是位于文件系统命名空间中的单向管道。 os.mkfifo()函数将在文件系统上创建管道。然后,您可以打开管道以在主进程中读取并打开它以便从shell子进程写入/直接输出到它。这应该简化您的代码并打开使用现有库(如Pexpect)与shell进行交互的选项。