나는 in 과 out을 Ctrl+D사용하여 읽으면 내 변수에 텍스트 전송 문자(EOT, ASCII 코드 4)가 끝나는 이유를 알아내려고 노력해 왔습니다 .read -N 1
bash
ksh93
나는 전송 끝 문자와 파일 끝 조건의 차이점을 알고 있으며 없이 Ctrl+D사용할 read
때 어떤 일이 발생하는지 알고 있습니다 -N
(EOT를 보내고 입력이 비어 있으면 기본 반환 값이 0이 되어 read()
EOF 신호를 보냅니다).
그러나 특정 수의 문자를 읽으려고 하면 이러한 동작이 왜 그렇게 크게 바뀌는지 잘 모르겠습니다. EOF 조건이 발생하고 다음 루프가 종료될 것으로 예상했습니다.
while read -N 1 ch; do
printf '%s' "$ch" | od
done
누르면 출력 Ctrl+D:
0000000 000004 0000001
설명서에는 다음 과 같이 bash
나와 있습니다 read -N
( ksh93
비슷한 문구 포함).
-N nchars
nchars
; 전체 입력 줄을 기다리지 않고 문자를 정확히 읽은 후 반환됩니다 .EOF를 만나지 않는 한또는 읽기 시간이 초과되었습니다.
...하지만 TTY를 원시/버퍼링되지 않은 모드로 전환하는 것에 대해서는 언급하지 않습니다(내 생각엔 무슨 일이 일어나고 있는지).
옵션은 와 동일하게 작동하는 -n
것으로 보이며 , 읽을 문자 수도 중요하지 않은 것 같습니다.read
Ctrl+D
입력 끝을 알리고 read -N
루프를 종료하려면 어떻게 해야 합니까(읽은 값을 테스트하는 것 외에),이것이 "알몸"과 다른 이유는 무엇입니까?read
?
답변1
문서에 ASCII EOF 같은 것이 없고 ^D의 ASCII 의미 체계가 EOT라고 명시되어 있으면 더 도움이 될 수 있습니다. 이는 터미널 드라이버가 표준 모드에서 제공하는 것입니다. 현재 전송인 read
.program 을 종료합니다.설명하다0 길이는 파일에서 EOF처럼 보이기 때문에 EOF로 읽히지만 터미널 드라이버는 문자 코드 4 제공을 거부하고 대신 이를 삼켜서 항상 원하는 것이 아닌 읽기를 종료합니다.
이것이 여기서 일어나는 일입니다. 제어 문자 의미 체계는 표준 모드의 일부입니다. 여기서 터미널 드라이버는 규칙에서 특별한 의미를 할당하는 문자를 볼 때까지 버퍼링합니다. 이는 EOT, BS, CR 및 기타 많은 경우에 해당됩니다( 모든 세부 사항을 보고 배우십시오) stty -a
.man termios
read -N
다음 N 문자만 전달하는 명시적 명령입니다. 이를 수행하려면 쉘은 터미널 드라이버에 표준 의미를 묻는 것을 중지해야 합니다.
그런데 EOF는 실제로 단말이 설정하거나 입력할 수 있는 조건이 아니다.
다른 것에 대해 eof를 계속 읽으면 EOF 표시기가 계속 표시되지만 터미널 드라이버가 제공할 수 있는 유일한 EOF는 가짜 EOF입니다. 생각해 보십시오. 터미널 드라이버가 실제로 실제 EOF를 제공한다면 쉘은 계속해서 읽을 수 없습니다. 모두 같은 터미널입니다. 여기:
#include <unistd.h>
#include <stdio.h>
char s[32];
int main(int c, char**v)
{
do {
c=read(0,s,sizeof s);
printf("%d,%.*s\n",c,c,s);
} while (c>=0);
}
터미널에서 시도해 보면 표준 모드의 터미널 드라이버가 EOT를 해석하여 미해결 읽기를 완료하고 읽기 버퍼링에 관계없이 표준 입력 종결자가 나타날 때까지 내부적으로 버퍼링하는 것을 볼 수 있습니다. 32바이트보다 길다).
당신을 혼란스럽게 하는 텍스트¸
EOF를 만나지 않는 한
실제 EOF를 나타냅니다.