简体   繁体   English

如何在循环中使用os.pipe()(复制多个管道)?

[英]How to use os.pipe() on loop (replicating multiple pipes)?

I am trying to replicate 'cat < hello.txt | cat | cat > hello2.txt' 我正在尝试复制'cat < hello.txt | cat | cat > hello2.txt' 'cat < hello.txt | cat | cat > hello2.txt' 'cat < hello.txt | cat | cat > hello2.txt' in python by only using os.pipe() . 仅使用os.pipe()在python中的'cat < hello.txt | cat | cat > hello2.txt' I am not trying to make something fancy, it is just for education(uni). 我不是想花哨的东西,只是为了教育。

I am really confused on how to do this. 我真的对如何做到这一点感到困惑。 But I am thinking of doing it as follows: 但是我正在考虑这样做,如下所示:

so i made a list of all commands between piping is to be performed - 所以我列出了要执行的管道之间所有命令的列表-

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

I am confused after this, who do i make it next command which is '/bin/cat' read from the output to perform the first piping ( cat < hello.txt | cat ) ? 在这之后,我感到困惑,我该如何使它成为下一个从输出中读取'/bin/cat'以执行第一个管道的命令( cat < hello.txt | cat )?

Also any hints on how to put it on loop so it is automated? 还有关于如何使其循环以使其自动化的提示吗? (I know the for loop i have used is wrong) (我知道我使用的for循环是错误的)

I know it is not the most optimal solution to perform piping but we are only taught os.pipe() and are refrained from using os.system and os.subprocess . 我知道这不是执行管道的最佳解决方案,但是我们只教过os.pipe() ,因此避免使用os.systemos.subprocess

Thanks in Advance 提前致谢

You look like you're going the right way with this. 您看起来好像在朝着正确的方向前进。

The basic idea is that stdin, stdout and/or stderr need to be replaced with a pipe for the processes to communicate with each other. 基本思想是需要用管道替换stdin,stdout和/或stderr,以便进程之间可以相互通信。 Since you'll be doing that several times, it's good to have a function for it. 由于您将多次执行该操作,因此最好具有一个功能。

eg 例如

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

Once you have the function, you can start to think about how you want to run the commands. 一旦有了该功能,就可以开始考虑如何运行命令。 I'll leave putting the loop to you, but it's something like the following. 我将把循环留给您,但这类似于以下内容。

# 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...

Once you've started all the processes, you just need to wait for them to finish. 一旦开始所有过程,您只需要等待它们完成即可。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM