【发布时间】:2020-09-18 12:35:21
【问题描述】:
我正在使用 os 库在 python 中制作一个 shell,我想制作多个管道功能,但我遇到了困难,因为我不确定如何处理 STDOUT 以及孩子和父母。
我想我必须继续将结果写入标准输出并复制它以防更多管道。
所以如果我有这个命令,我应该只得到找到 var 的那一行:
ls -l / | grep v | grep var
然后我让 shell 将命令分成一个字符串列表:
command = [['ls', '-l', '/'], ['grep', 'root'], ['grep', 'var']]
然后我需要将前两个的输出分叉并复制到一个新的孩子中,并将输出传递给最后一个。
我真的很困惑如何使用超过 1 个管道做到这一点,更困惑于如何动态地做到这一点。
我现在坐下来尝试不同的方法来静态添加第二个管道到程序中,但我有一些想法应该如何动态添加 n 个管道到程序中通过使用迭代或递归。
我做一个管道的工作代码是这样的:
from os import (
execvp,
wait,
fork,
pipe,
dup2,
_exit,
close,
)
STDIN = 0
STDOUT = 1
CHILD = 0
def command(cmd):
try:
execvp(cmd[0].strip(), cmd)
except OSError as e:
print(e)
def piping(cmd):
reading, writing = pipe()
pid = fork()
if pid > CHILD:
wait()
close(writing)
dup2(reading, STDIN)
command(cmd[1])
elif pid == CHILD:
close(reading)
dup2(writing, STDOUT)
command(cmd[0])
_exit(0)
def main():
pid = fork()
if pid > CHILD:
wait()
if pid == CHILD:
piping([['ls','-al','/'],['grep','v'],['grep','var']])
_exit(0)
main()
所以要使用 3 个管道,我想我可以做这样的事情。但它不起作用。
我只是更改了 pipe() 函数以在 child 内部获得一个额外的 fork,并使用 dup2 方法交换新旧管道中通道的输入/输出。
def piping(cmd):
print(cmd)
r1 , w1 = pipe()
pid = fork()
if pid > CHILD:
wait()
close(w1)
dup2(r1, STDIN)
command(cmd[2])
elif pid == CHILD:
r2, w2 = pipe()
pid2 = fork()
if pid2 > CHILD:
wait()
close(w2)
close(r1)
dup2(w1, r2)
command(cmd[1])
elif pid2 == CHILD:
close(r2)
dup2(w2, STDOUT)
command(cmd[0])
_exit(0)
请帮帮我,我真的很想学习如何做到这一点!谢谢:-)
【问题讨论】:
-
re:“我想我必须继续将结果写入标准输出并复制它以防更多管道。”您不希望您的 shell 读取它生成的子节点的任何输出。在管道
a | b | c中,shell 仅运行b,其标准输入位于a的标准输出的管道另一端。如果您的 shell 正在读取a的输出并将其写入b,那么您做错了。 -
我正在写一个 |和阅读| b 但我想如果我有 3 个管道:那么我必须写一个 |写 |乙 |并阅读 | c,所以这阻止我在孩子内部调用相同的函数,因为我总是写一个 |和阅读|乙。
-
也许我必须创建一个可以返回相关管道通道的函数。
-
我想我现在明白了!!!! :D :D
标签: python pipe fork python-os