복붙노트

[PYTHON] 초보자 파이썬 하위 프로세스 : "쓰기 오류 : 브로큰 파이프"

PYTHON

초보자 파이썬 하위 프로세스 : "쓰기 오류 : 브로큰 파이프"

아래의 유용한 제안에 감사드립니다.

그래서 내가 고정 될 때 보인다.

새로운 코드 :

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)

원본 게시물 :

간단한 프로세스를 파이핑하는 문제를 해결하기 위해 너무 오랜 시간을 보냈습니다.

암호:

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 ()를 가지고 놀았다. 나는 'sleep 20; 고양이 moderatefile '하지만 이것은 오류없이 실행하는 것 같습니다.

해결법

  1. ==============================

    1.서브 프로세스 문서의 요리법 :

    서브 프로세스 문서의 요리법 :

    # 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]
    
  2. ==============================

    2.이것은 subprocess.Popen에 전달 된 명령에서 "셸 파이프"를 사용하면 안되기 때문에 다음과 같이 subprocess.PIPE를 사용해야합니다.

    이것은 subprocess.Popen에 전달 된 명령에서 "셸 파이프"를 사용하면 안되기 때문에 다음과 같이 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()
    

    하지만 당신이하려는 일은 쉘 명령을 호출하는 대신 순수한 파이썬으로 할 수 있다고 말해야합니다.

  3. ==============================

    3.나는 같은 오류를 겪고있다. 파이프를 bash 스크립트에 넣고 파이썬에서 파이프 대신 실행했습니다. 파이썬에서는 깨진 파이프 오류가 발생할 것입니다. bash에서는 그렇지 않습니다.

    나는 같은 오류를 겪고있다. 파이프를 bash 스크립트에 넣고 파이썬에서 파이프 대신 실행했습니다. 파이썬에서는 깨진 파이프 오류가 발생할 것입니다. bash에서는 그렇지 않습니다.

    아마 머리 이전의 마지막 명령이 (정렬) STDOUT이 닫히는 동안 오류를 던지고있는 것 같습니다. 파이썬은 이것에 의존하고 있어야하지만 쉘에서는 오류가 없다. 전체 코드를 사용하도록 코드를 변경 했으므로 오류가 사라졌습니다.

    헤드가 종료되기 전에 파이프가 아마 전체 출력을 버퍼링하기 때문에 더 작은 파일로 작업하는 것도 의미가 있습니다. 이것은 큰 파일의 중단을 설명합니다.

    예를 들어, 'head -1'대신에 (내 경우에는 첫 번째 줄만 원했다) awk 'NR == 1'

    파이프에서 'head -X'가 어디에서 발생하는지에 따라 더 나은 방법이있을 수 있습니다.

  4. ==============================

    4.shell = True는 필요 없습니다. 쉘을 호출하지 마십시오. 이것이 내가하는 방법이다.

    shell = True는 필요 없습니다. 쉘을 호출하지 마십시오. 이것이 내가하는 방법이다.

    p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    stdout_value = p.communicate()[0] 
    stdout_value   # the output
    

    이것을 사용한 후에 버퍼에 관한 문제가 발생했는지 확인하십시오.

  5. ==============================

    5.stdout에서 직접 읽는 것이 아니라, communicate ()를 사용해보십시오.

    stdout에서 직접 읽는 것이 아니라, communicate ()를 사용해보십시오.

    파이썬 docs는 이것을 말한다 :

    http://docs.python.org/library/subprocess.html#subprocess.Popen.stdout

    p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    output =  p.communicate[0]
    for line in output:
        # do stuff
    
  6. from https://stackoverflow.com/questions/4106565/newbie-python-subprocess-write-error-broken-pipe by cc-by-sa and MIT license