bash : echo : 쓰기 오류 : 시스템 호출 중단


9

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

이 세 가지 오류가 발생하고 결과가 잘못되었습니다.

나는 사용한다

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

데비안 GNU / 리눅스 9.6 (스트레치)

리눅스 커널 : 4.19.0 # 2 SMP Thu 11 월 1 일 15:31:34 EET 2018 x86_64 GNU / Linux


2
나는 도울 수는 없지만 그렇게하는 느낌이 더 효율적이지 않을 것 seq -w 0 99999999입니다.
Kusalananda

1
그런 다음 질문이 불완전하거나 잘못되었거나 잘못 쓰여졌거나 다른 것입니다. 스크립트 (로 완료시 })가 올바르게 작동하기 때문입니다. @ GAD3R
Isaac 10

1
참고 :이 오류는 거의 필요할 때 트리거 할 수 있습니다. konsole창 크기를 조정할 때 종종 나타납니다 . 필자의 경우에는 이러한 크기 조정이 거의 충분하지만 필요하지는 않습니다.
Kamil Maciorowski

을 제거해도 | tee result.txt여전히 오류가 발생합니다.
ctrl-alt-delor

또 다른 참고 사항 : 내장형 /bin/echo대신 외부 실행 파일 ( 제 경우) echo은이 문제에 면역 기능 (또는 최소한 덜 취약한)을 만듭니다.
Kamil Maciorowski

답변:


6

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

하기 :

 trap '' SIGWINCH

피할 것이다.

참고

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

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


5
그래서 무슨 일이야?, 왜 내가 전에 이것을 보지 못했습니까?, 왜 쓰기 오류가 올바른 것입니까?
ctrl-alt-delor

4

이것은 실제로 버그 [1] 이며 bash에서만 발생하는 SIGWINCH것이 아니라 트랩이 설정된 신호에서도 발생합니다 .

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

이 때문에 일어난다 bash) 중 어느 하나에 장애가와의 신호 처리기를 설정 SA_RESTART제외 ( SIGCHLD핸들러), 또는 B)을 처리 EINTR호출시 write()printfecho내장 매크로.

EINTR( "중단 된 시스템 호출")은 오류 조건을 나타내는 방법이 아니라 프로그래머가 블로킹 읽기 / 쓰기 등을 메인 루프의 신호 처리와 결합 할 수있는 해킹입니다. 사용자에게 누출되지 않아야합니다.

이 버그는 올바른 조건을 제대로 구현하는 데 매우 적합하기 때문에 너무 자주 표시되지 않습니다 . 외부 명령이 아닌 내장 명령write() 으로 수행 해야하고 파이프 버퍼 (다른 쪽 판독기)를 채워야합니다. end는 훨씬 느리거나 파이프에서 읽지 않아야 하지만 여전히 살아 있어야합니다) 스크립트는 트랩을 사용하거나 터미널 창의 크기를 조정해야합니다.

그리고 다양한 구현 아티팩트 때문에 이는 s 또는 s가 write()아닌 인터럽트 된 s 에만 영향을 미칩니다 (예 : 명명 된 파이프 / fifo 차단 ).read()open()open()

[1] 이것의 어떤 형태는 이미 얼마 전에 보고 되었다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.