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_RESTART
SIGCHLD
EINTR
write()
printf
echo
EINTR
("중단된 시스템 호출")은 오류 상태를 나타내는 방법이 아니라 프로그래머가 차단 읽기/쓰기 등을 메인 루프의 신호 처리와 결합할 수 있도록 하는 방법입니다. 절대 사용자에게 유출되어서는 안 됩니다.
이 오류는 너무 자주 발생하지 않습니다. 조건을 올바르게 설정하는 것은 대단한 일이기 때문입니다 write()
.내장(외부 명령을 통해서가 아님) 파이프 버퍼를 채워야 합니다(다른 쪽 끝에 있는 리더는많은파이프에서 읽히는 속도가 느리거나 전혀 읽히지 않음하지만 아직 살아있다) 스크립트는 트랩을 사용하거나 터미널 창의 크기를 조정해야 합니다.
그리고 구현 아티팩트가 다르기 때문에 이는 중단된 write()
s read()
나 s가 아닌 중단된 open()
s에만 영향을 미칩니다(예: open()
명명된 파이프/fifos 차단).
[1]이 양식은 이미 존재합니다.보고서전자.