IOError : [Errno 32] 깨진 파이프 : Python
매우 간단한 Python 3 스크립트가 있습니다.
f1 = open('a.txt', 'r')
print(f1.readlines())
f2 = open('b.txt', 'r')
print(f2.readlines())
f3 = open('c.txt', 'r')
print(f3.readlines())
f4 = open('d.txt', 'r')
print(f4.readlines())
f1.close()
f2.close()
f3.close()
f4.close()
그러나 항상 다음과 같이 말합니다.
IOError: [Errno 32] Broken pipe
인터넷에서이 문제를 해결하는 모든 복잡한 방법을 보았지만이 코드를 직접 복사했기 때문에 Python의 SIGPIPE가 아니라 코드에 문제가 있다고 생각합니다.
출력을 리디렉션하고 있으므로 위 스크립트의 이름이 "open.py"인 경우 실행할 명령은 다음과 같습니다.
open.py | othercommand
나는 문제를 재현하지 않았지만 아마도이 방법으로 해결할 수 있습니다. ( stdout
사용 하는 대신 한 줄씩 쓰기 print
)
import sys
with open('a.txt', 'r') as f1:
for line in f1:
sys.stdout.write(line)
깨진 파이프를 잡을 수 있습니까? stdout
파이프가 닫힐 때까지 파일을 한 줄씩 기록합니다 .
import sys, errno
try:
with open('a.txt', 'r') as f1:
for line in f1:
sys.stdout.write(line)
except IOError as e:
if e.errno == errno.EPIPE:
# Handle error
또한 othercommand
파이프가 너무 커지기 전에 파이프에서 읽고 있는지 확인해야합니다 -https: //unix.stackexchange.com/questions/11946/how-big-is-the-pipe-buffer
문제는 SIGPIPE 처리 때문입니다. 다음 코드를 사용하여이 문제를 해결할 수 있습니다.
from signal import signal, SIGPIPE, SIG_DFL
signal(SIGPIPE,SIG_DFL)
이 솔루션에 대한 배경 정보는 여기 를 참조하십시오 . 여기에 더 나은 대답 .
가져 알렉스 L.의 도움이 대답 , akhan의 도움이 대답 하고, Blckknght의 도움이 대답을 몇 가지 추가 정보와 함께 :
표준 유닉스 신호가
SIGPIPE
프로세스로 전송 쓰기 A를 파이프 어떤 프로세스가 없을 때 읽기 파이프 (더 이상)에서이.- 이것은 반드시 오류 조건 은 아닙니다 .
head
설계 상 일부 유닉스 유틸리티 는 충분한 데이터를 수신하면 파이프에서 읽기를 일찍 중지합니다.
- 이것은 반드시 오류 조건 은 아닙니다 .
기본적으로 -즉, 쓰기 프로세스가 명시 적으로 트랩 하지 않는 경우
SIGPIPE
-쓰기 프로세스가 단순히 종료 되고 종료 코드가로 설정됩니다141
. 이는128
(일반적으로 신호에 의한 신호 종료) +13
(SIGPIPE
의 특정 신호 번호 )로 계산됩니다. .그러나 설계 상 Python 자체
SIGPIPE
가 값이 있는 PythonIOError
인스턴스 로 트랩 하고 변환 하므로 Python 스크립트가 원하는 경우이를 포착 할 수 있습니다 . 수행 방법 은 Alex L.의 답변 을 참조하십시오 .errno
errno.EPIPE
파이썬 경우 스크립트가 않습니다 하지 그것을 잡기 , 파이썬 출력 오류 메시지
IOError: [Errno 32] Broken pipe
및 종료 코드와 스크립트를 종료1
-이 증상 영업 톱이다.대부분의 경우 이것은 도움이되는 것보다 방해가 되므로 기본 동작으로 되 돌리는 것이 바람직합니다 .
은 Using
signal
모듈을 수 있습니다 만, 그에 명시된 바와 같이 akhan의 대답 ;signal.signal()
처리 할 신호를 첫 번째 인수로, 핸들러를 두 번째 인수로받습니다. 특수 핸들러 값SIG_DFL
은 시스템의 기본 동작을 나타냅니다 .from signal import signal, SIGPIPE, SIG_DFL signal(SIGPIPE, SIG_DFL)
다른 쪽 끝에서 닫힌 파이프에 쓰려고하면 "Broken Pipe"오류가 발생합니다. 당신이 보여준 코드는 파이프를 직접적으로 포함하지 않기 때문에, 나는 당신이 파이썬 인터프리터의 표준 출력을 다른 곳으로 리디렉션하기 위해 파이썬 외부에서 무언가를하고 있다고 생각합니다. 다음과 같은 스크립트를 실행하는 경우 발생할 수 있습니다.
python foo.py | someothercommand
문제 someothercommand
는 표준 입력에서 사용할 수있는 모든 것을 읽지 않고 종료 된다는 것 입니다. 이로 인해 (를 통한 print
) 쓰기 가 어느 시점에서 실패합니다.
Linux 시스템에서 다음 명령을 사용하여 오류를 재현 할 수있었습니다.
python -c 'for i in range(1000): print i' | less
less
모든 입력 (1000 줄)을 스크롤하지 않고 호출기를 닫으면 Python IOError
이보고 한 것과 동일하게 종료됩니다 .
나는 사용하는 방법을 지적해야 할 의무가 있다고 느낍니다.
signal(SIGPIPE, SIG_DFL)
실제로 위험합니다 (이미 David Bennet이 의견에서 제안했듯이). 내 경우에는 multiprocessing.Manager
(표준 라이브러리가 여러 곳에서 발생하는 BrokenPipeError에 의존하기 때문에) 플랫폼에 의존하는 재미있는 비즈니스 로 이어졌습니다. 길고 고통스러운 이야기를 짧게 만들기 위해 다음과 같이 수정했습니다.
먼저 IOError
(Python 2) 또는 BrokenPipeError
(Python 3) 을 잡아야합니다 . 프로그램에 따라 해당 시점에서 일찍 종료하거나 예외를 무시할 수 있습니다.
from errno import EPIPE
try:
broken_pipe_exception = BrokenPipeError
except NameError: # Python 2
broken_pipe_exception = IOError
try:
YOUR CODE GOES HERE
except broken_pipe_exception as exc:
if broken_pipe_exception == IOError:
if exc.errno != EPIPE:
raise
그러나 이것만으로는 충분하지 않습니다. Python 3은 여전히 다음과 같은 메시지를 인쇄 할 수 있습니다.
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
BrokenPipeError: [Errno 32] Broken pipe
Unfortunately getting rid of that message is not straightforward, but I finally found http://bugs.python.org/issue11380 where Robert Collins suggests this workaround that I turned into a decorator you can wrap your main function with (yes, that's some crazy indentation):
from functools import wraps
from sys import exit, stderr, stdout
from traceback import print_exc
def suppress_broken_pipe_msg(f):
@wraps(f)
def wrapper(*args, **kwargs):
try:
return f(*args, **kwargs)
except SystemExit:
raise
except:
print_exc()
exit(1)
finally:
try:
stdout.flush()
finally:
try:
stdout.close()
finally:
try:
stderr.flush()
finally:
stderr.close()
return wrapper
@suppress_broken_pipe_msg
def main():
YOUR CODE GOES HERE
This can also occur if the read end of the output from your script dies prematurely
ie open.py | otherCommand
if otherCommand exits and open.py tries to write to stdout
I had a bad gawk script that did this lovely to me.
I know this is not the "proper" way to do it, but if you are simply interested in getting rid of the error message, you could try this workaround:
python your_python_code.py 2> /dev/null | other_command
Closes should be done in reverse order of the opens.
참고URL : https://stackoverflow.com/questions/14207708/ioerror-errno-32-broken-pipe-python
'Programing' 카테고리의 다른 글
Eclipse CDT에서 가장 유용한 단축키 (0) | 2020.10.11 |
---|---|
NSString의 하위 문자열을 얻는 방법? (0) | 2020.10.11 |
디렉토리를 쓰기 가능하게하려면 어떻게해야합니까? (0) | 2020.10.11 |
Python의 요청 모듈을 사용하여 웹 사이트에 "로그인"하는 방법은 무엇입니까? (0) | 2020.10.11 |
iOS : 프로그래밍 방식으로 UILabel의 글꼴 크기 설정 (0) | 2020.10.11 |