Python-如何使用subprocess.Popen通过管道连接多个进程?

发布于 2021-02-02 23:22:54

如何使用Python subprocess模块执行以下shell命令?

echo "input data" | awk -f script.awk | sort > outfile.txt

输入数据将来自字符串,因此我实际上并不需要echo。我已经走了这么远,还有谁能解释我也可以通过它进行管道传输sort吗?

p_awk = subprocess.Popen(["awk","-f","script.awk"],
                          stdin=subprocess.PIPE,
                          stdout=file("outfile.txt", "w"))
p_awk.communicate( "input data" )

更新:请注意,尽管下面接受的答案实际上并没有回答所提出的问题,但我相信S.Lott是正确的,最好避免首先解决该问题!

关注者
0
被浏览
199
1 个回答
  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。

    您将对以下内容感到满意。

    import subprocess
    
    awk_sort = subprocess.Popen( "awk -f script.awk | sort > outfile.txt",
        stdin=subprocess.PIPE, shell=True )
    awk_sort.communicate( b"input data\n" )
    

    将部分工作委托给外壳。让它通过管道连接两个进程。

    您将更高兴地将“ script.awk”重写为Python,从而消除了awk和管道。

    编辑。提示awk没有帮助的一些原因。

    [有太多原因需要通过评论做出回应。]

    Awk正在添加没有重大价值的步骤。awk的处理过程没有Python无法处理的独特之处。

    对于大量数据,从awk到排序的流水线操作可能会缩短处理时间。对于短数据集,它没有明显的好处。快速测量awk >file ; sort file并awk | sort揭示并发性会有所帮助。使用sort时,它很少有帮助,因为sort不是一次性过滤器。

    “ Python进行排序”处理(而不是“ Python进行awk进行排序”)的简单性避免了在此处询问确切类型的问题。

    Python虽然比awk更为冗长,但也很明显,其中awk具有某些对新手来说是不透明的隐式规则,这会使非专业人士感到困惑。

    Awk(类似于shell脚本本身)添加了Another Another Programming语言。如果所有这些都可以用一种语言(Python)来完成,则无需使用shell,而awk编程可以消除两种编程语言,从而使人们可以专注于任务的价值创造部分。

    底线:awk不能增加可观的价值。在这种情况下,awk是净成本;它增加了足够的复杂性,因此有必要提出这个问题。删除awk将获得净收益。

    补充工具栏为什么构建管道(a | b)如此困难。

    遇到外壳时a | b,必须执行以下操作。

    分叉原始外壳的子进程。最终将成为b。

    建立一个OS管道。(不是Python subprocess.PIPE),但调用os.pipe()返回两个通过公共缓冲区连接的新文件描述符。此时,该进程具有来自其父级的stdin,stdout,stderr,外加一个文件“ a's stdout”“ b's stdin”

    分叉一个孩子。子代将其标准输出替换为新的a的标准输出。执行该a过程。

    b子关闭,用新b的stdin替换其stdin。执行该b过程。

    b子等待a完成。

    父级正在等待b完成。

    我认为上面的代码可以递归生成a | b | c,但是您必须隐式地括住长管道,将它们视为a | (b | c)

    由于Python有os.pipe(),os.exec()并且os.fork(),你可以替换sys.stdinsys.stdout,有一种方法做上述纯Python。确实,您可以使用os.pipe()和确定一些快捷方式subprocess.Popen

    但是,将该操作委托给Shell会更容易。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看