【问题标题】:How to use os.pipe() on loop (replicating multiple pipes)?如何在循环中使用 os.pipe()(复制多个管道)?
【发布时间】:2019-03-19 01:34:04
【问题描述】:

我正在尝试仅使用 os.pipe() 在 python 中复制 'cat < hello.txt | cat | cat > hello2.txt'。我不是想制造一些花哨的东西,它只是为了教育(uni)。

我真的很困惑如何做到这一点。但我正在考虑这样做:

所以我列出了管道之间要执行的所有命令 -

pipe_commands = [['/bin/cat < hello.txt'] , ['/bin/cat'], ['/bin/cat > hello2']]

for i in pipe_command:
    r, w = os.pipe()
    if '<' in i:
        pid =  os.fork() 
        if pid == 0:
            os.close(r)
            w = os.fdopen(w, 'w')   # Start Writting on write end of pipe 
            os.dup2(w.fileno(), sys.stdout.fileno())

            f= open('hello.txt', 'r')   # start reading from hello.txt 
            os.dup2(f.fileno(), sys.stdin.fileno())

            os.execl('/bin/echo', 'echo')
    else:
        os.wait()
        os.close(w)
        r = os.fdopen(r, 'r')
        os.dup2(r.fileno(), sys.stdin.fileno()) # read from read end of pipe 
        # OUTPUT TO BE GIVEN TO NEXT COMMAND

    elif '>' in i:

        pid =  os.fork() 

        if pid == 0:

            os.close(w)         # Start reading from previous commands pipe output 
            r = os.fdopen(r, 'r')
            os.dup2(r.fileno(), sys.stdin.fileno())

            f = open('hello2.txt', 'w')     # write to hello2.txt
            os.dup2(f.fileno(), sys.stdout.fileno())

            os.execl('/bin/echo', 'echo')

        else:
            os.wait()

    else:
        pid =  os.fork() 
        if pid == 0:
            os.close(r)
            w = os.fdopen(w, 'w')   # Start Writting on write end of pipe 
            os.dup2(w.fileno(), sys.stdout.fileno())

            os.execl('/bin/echo', 'echo')   #input from read end of the previous command  
        else:
            os.wait()
            os.close(w)
            r = os.fdopen(r, 'r')
            os.dup2(r.fileno(), sys.stdin.fileno()) # read from read end of pipe 
        # OUTPUT TO BE GIVEN TO NEXT COMMAND

在此之后我很困惑,我该让谁执行下一个命令,即从输出中读取 '/bin/cat' 以执行第一个管道 (cat &lt; hello.txt | cat)?

还有关于如何将其置于循环以使其自动化的任何提示? (我知道我使用的 for 循环是错误的)

我知道这不是执行管道的最佳解决方案,但我们只接受了os.pipe() 的培训,并避免使用os.systemos.subprocess

提前致谢

【问题讨论】:

  • 您的代码甚至无法编译。请修正错误。您似乎有一些语法错误和一些错误的缩进,这弄乱了完整的程序逻辑。
  • @Corion 嗨,它更像是一个伪代码而不是实际代码,让读者了解我的前进方向。我直接在问题窗口中编写了代码,甚至没有检查它是否正在编译。

标签: python linux python-3.x bash python-2.7


【解决方案1】:

您看起来好像走对了。

基本思想是stdin、stdout 和/或stderr 需要替换为管道,以便进程相互通信。由于您将多次这样做,因此最好有一个函数。

例如

def start_process(command, newin, newout, newerr):
    pid = os.fork()
    if pid == 0:
        # Child process
        os.dup2(newin, 0)  # Replace stdin
        os.dup2(newout, 1)  # Replace stdout
        os.dup2(newerr, 2)  # Replace stderr
        os.execv(command, (command,))
    else:
        # Parent process
        return pid

一旦你有了这个功能,你就可以开始考虑你想如何运行这些命令。我将把循环留给你,但它类似于以下内容。

# cat < hello.txt
# stdin=hello.txt, stdout=pipe1, stderr=unchanged
hello = open('hello.txt', 'r')
pipe1_read, pipe1_write = os.pipe()
proc1 = start_process('/bin/cat', hello.fileno(), pipe1_write, sys.stderr.fileno())
os.close(pipe1_write)  # only proc1 should have this

# /bin/cat
# stdin=pipe1 stdout=pipe2, stderr=unchanged
pipe2_read, pipe2_write = os.pipe()
proc2 = start_process('/bin/cat', pipe1_read, pipe2_write, sys.stderr.fileno())
os.close(pipe2_write)  # only proc2 should have this

# etc...

一旦你开始了所有的过程,你只需要等待它们完成。

os.waitpid(proc1, 0)
os.waitpid(proc2, 0)
os.waitpid(proc3, 0)

【讨论】:

  • 你是个传奇人物,再好不过了。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-29
  • 2020-07-03
  • 2020-09-27
  • 1970-01-01
相关资源
最近更新 更多