新手python子进程:“写入错误:断开的管道”

感谢以下有用的建议:

所以它似乎是固定的,当我

  • 将命令分成对Popen的个别呼叫
  • stderr = subprocess.PIPE作为每个Popen链的参数。
  • 新代码:

    import subprocess
    import shlex
    import logging
    
    def run_shell_commands(cmds):
        """ Run commands and return output from last call to subprocess.Popen.
            For usage see the test below.
        """
        # split the commands
        cmds = cmds.split("|")
        cmds = list(map(shlex.split,cmds))
    
        logging.info('%s' % (cmds,))
    
        # run the commands
        stdout_old = None
        stderr_old = None
        p = []
        for cmd in cmds:
            logging.info('%s' % (cmd,))
            p.append(subprocess.Popen(cmd,stdin=stdout_old,stdout=subprocess.PIPE,stderr=subprocess.PIPE))
            stdout_old = p[-1].stdout
            stderr_old = p[-1].stderr
        return p[-1]
    
    
    pattern = '"^85567      "'
    file = "j"
    
    cmd1 = 'grep %s %s | sort -g -k3 | head -10 | cut -d" " -f2,3' % (pattern, file)
    p = run_shell_commands(cmd1)
    out = p.communicate()
    print(out)
    

    原帖:

    我花了太长时间试图解决管道一个简单的子进程问题.Popen。

    码:

    import subprocess
    cmd = 'cat file | sort -g -k3 | head -20 | cut -f2,3' % (pattern,file)
    p = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE)
    for line in p.stdout:
        print(line.decode().strip())
    

    输出文件〜1000行的长度:

    ...
    sort: write failed: standard output: Broken pipe
    sort: write error
    

    文件输出> 241行:

    ...
    sort: fflush failed: standard output: Broken pipe
    sort: write error
    

    文件<241行的输出很好。

    我一直在阅读文档和疯狂搜索,但有一些基本的关于子程序模块,我错过了...也许与缓冲区有关。 我试过p.stdout.flush()和缓冲区大小和p.wait()。 我试图用“睡眠20; 猫中等文件“,但这似乎运行没有错误。


    从子流程文档的配方:

    # To replace shell pipeline like output=`dmesg | grep hda`
    p1 = Popen(["dmesg"], stdout=PIPE)
    p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
    output = p2.communicate()[0]
    

    这是因为你不应该在传递给subprocess.Popen的命令中使用“shell管道”,你应该像这样使用subprocess.PIPE

    from subprocess import Popen, PIPE
    
    p1 = Popen('cat file', stdout=PIPE)
    p2 = Popen('sort -g -k 3', stdin=p1.stdout, stdout=PIPE)
    p3 = Popen('head -20', stdin=p2.stdout, stdout=PIPE)
    p4 = Popen('cut -f2,3', stdin=p3.stdout)
    final_output = p4.stdout.read()
    

    但是我不得不说,你正在试图做的事情可以用纯Python来完成,而不是调用一堆shell命令。


    我一直有同样的错误。 甚至把管道放在一个bash脚本中,并执行它,而不是Python中的管道。 从Python它会得到损坏的管道错误,从bash它不会。

    在我看来,也许在头部之前的最后一个命令会抛出一个错误,因为它的(排序)STDOUT是关闭的。 Python必须在这方面采取行动,而在shell中,错误是无声的。 我更改了我的代码以消耗整个输入,并且错误消失了。

    对于较小的文件也是有意义的,因为管道可能在磁头退出前缓冲整个输出。 这将解释更大的文件的休息。

    例如,而不是'head -1'(在我的情况下,我只想要第一行),我做了一个awk'NR == 1'

    根据管道中'head -X'的位置,可能有更好的方法。

    链接地址: http://www.djcxy.com/p/13475.html

    上一篇: newbie python subprocess: "write error: Broken pipe"

    下一篇: How to pipe stderr, and not stdout?