bash: 에코: 쓰기 오류: 시스템 호출이 중단되었습니다.

bash: 에코: 쓰기 오류: 시스템 호출이 중단되었습니다.

00000000부터 99999999까지 8자리 숫자를 모두 포함하는 정렬된 목록을 생성하고 싶습니다. 나는 쉘에 다음을 입력했다:

f() {
 while IFS="" read -r line; do
   for i in {0..9}; do 
       echo "$line$i";
   done;
 done
}

echo | f | f | f | f | f | f | f | f | tee result.txt | wc -l

응답은 다음과 같습니다

bash: echo: write error: Interrupted system call
bash: echo: write error: Interrupted system call
bash: echo: write error: Interrupted system call
99998890

이 세 가지 오류와 잘못된 result.txt가 나타나는 이유는 무엇입니까?

나는 사용한다

GNU bash, 버전 4.4.12(1)-릴리스(x86_64-pc-linux-gnu)

Debian GNU/Linux 9.6(확장)

Linux 커널: 4.19.0 #2 SMP Thu Nov 1 15:31:34 EET 2018 x86_64 GNU/Linux

답변1

write error: Interrupted system call스크립트를 실행하는 동안 콘솔 창 크기를 변경하면 특정 오류가 생성됩니다.

어떤 것을 만들어:

 trap '' SIGWINCH

그것을 피할 것입니다.

참고하시기 바랍니다

 seq 99999999 >result.txt; wc -l <result.txt

더 빠르고 이 SIGWINCH문제를 피할 수 있습니다.

답변2

이건 사실 버그에요[1]in bash, 이는 on 뿐만 아니라 SIGWINCH트랩이 설정된 모든 신호에서도 발생합니다.

{ pid=$BASHPID; trap : USR1; (sleep 1; kill -USR1 $pid) &
         printf %0100000d 1; } | sleep 3600
bash: printf: write error: Interrupted system call

이는 a) 신호 처리기 ( handler 제외 ) bash를 설정하거나 b) 내장 함수를 호출할 때 신호 처리기를 처리하는 데 실패했기 때문에 발생합니다 .SA_RESTARTSIGCHLDEINTRwrite()printfecho

EINTR("중단된 시스템 호출")은 오류 상태를 나타내는 방법이 아니라 프로그래머가 차단 읽기/쓰기 등을 메인 루프의 신호 처리와 결합할 수 있도록 하는 방법입니다. 절대 사용자에게 유출되어서는 안 됩니다.

이 오류는 너무 자주 발생하지 않습니다. 조건을 올바르게 설정하는 것은 대단한 일이기 때문입니다 write().내장(외부 명령을 통해서가 아님) 파이프 버퍼를 채워야 합니다(다른 쪽 끝에 있는 리더는많은파이프에서 읽히는 속도가 느리거나 전혀 읽히지 않음하지만 아직 살아있다) 스크립트는 트랩을 사용하거나 터미널 창의 크기를 조정해야 합니다.

그리고 구현 아티팩트가 다르기 때문에 이는 중단된 write()s read()나 s가 아닌 중단된 open()s에만 영향을 미칩니다(예: open()명명된 파이프/fifos 차단).

[1]이 양식은 이미 존재합니다.보고서전자.

관련 정보