/dev/null
작성된 모든 내용을 삭제하고 EOF
읽을 때 사용할 수 있도록 하는 특수 Linux 파일입니다.
/dev/null
나는 이것을 독서를 통해 얻고 시각화하고 싶었습니다 EOF
. 내가 시도하면 :
$ cat /dev/null | hexdump
이것은 작동하지 않습니다. 출력 없이 프롬프트로 돌아갑니다. EOF
ASCII 코드조차 없기 때문에 그럴 수도 있습니다.
그래도
EOF
캐릭터라고 볼 수 있나요?EOF
Bash에서 제공되는 경우 이를 감지하고 인쇄할 수 있는 방법이 있습니까stdin
?
그것은 다음과 같습니다:
$ cat /dev/null | some_tool
EOF
저는 Ubuntu 20.04.3을 사용하고 있지만 GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)
솔루션이 있다면 이러한 특정 버전과 독립적이기를 바랍니다.
이것은아니요숙제이지만 더 많은 것을 배울 수 있는 방법일 뿐입니다 EOF
.
답변1
원래 ASCII 제어 문자 집합에 정의된 일련의 "{something} 끝" 문자가 있지만 EOF는 문자가 아닙니다. EOF는 입력 스트림에서 더 이상 읽을 수 없기 때문에 감지 가능한 조건입니다.
예를 들어, 이 루프는 더 이상 읽을 내용이 없을 때까지(즉, EOF에 도달할 때까지) 계속됩니다.
{
while IFS= read -r line; do
printf '%s\n' "Read: >> $line <<"
done
if [ -n "$line" ]; then
printf '%s\n' "And some extra data after the last line: >> $line <<"
fi
echo 'No more'
}
또는 더 효율적으로(일부 구현에서는 NUL 바이트를 차단하지 않음 sed
) 쉘 루프를 완전히 피하십시오.
LC_ALL=C sed 's/.*/Read: >> & <</'; echo 'No more'
(마지막 행 뒤에 데이터가 있는 경우 No more
해당 행의 접두사로 사용합니다.)
터미널의 기본 설정은 키를 ^D
누를 때 터미널에서 보낸 문자가 Ctrl D터미널 드라이버에 의해 EOF를 나타내는 것으로 해석된다는 것입니다. 그러나 해당 문자(또는 다른 문자 )를 응용 프로그램에 보내지 않습니다. tty 장치 파일의 s가 읽을 내용을 반환하도록 하고 , read()
아무것도 없으면 응용 프로그램은 이를 EOF로 해석합니다. 터미널 장치의 현재 EOF 문자). 자체 줄 편집기를 구현하는 셸이나 기타 응용 프로그램은 일반적으로 이 문자를 동일한 방식으로 처리합니다(적어도 빈 줄 버퍼에 있는 경우).stty -a
eof
답변2
얻을 수 있는 /dev/null
것은 read()
시스템 호출이 성공적으로 반환되고 0바이트가 읽힌다는 것뿐입니다. 이는 파일 끝에서(또는 그 이후) 시작하려고 할 때 발생하는 것과 동일하므로 read()
"파일 끝"이라고 합니다.
그러나 터미널과 같이 한 번의 호출에서 0바이트를 반환할 수 있지만(사용자가 ^D
빈 행을 클릭하거나 다른 호출 후에 ^D
) 다음 읽기에서 더 많은 데이터를 반환하는 이상한 경우도 있습니다. 0바이트 데이터그램을 지원할 수 있는 데이터그램 소켓도 있으며 시스템은 이러한 데이터그램에 대해 0바이트를 반환하지만 다음 호출에서는 여전히 다음 데이터그램을 반환합니다. 물론 read()
마지막에 파일에서 0바이트를 얻을 수도 있지만 나중에 다시 호출을 시도하면 이번에는 더 많은 데이터가 대기 중인 것을 발견하게 될 것입니다. (이것은 tail -f
구현이 수행할 수 있는 작업입니다.)
인쇄할 것이 없기 때문에 실제로 "EOF를 인쇄"할 수 없습니다. 단지 데이터가 부족할 뿐입니다.
EOF에서의 종료를 알면 cat
확실히 다음과 같은 작업을 수행할 수 있습니다.
(cat /dev/null; echo EOF) | whatever...
완료되면 무언가를 인쇄하십시오. 제 생각에는 이것은 그다지 유용하지 않습니다.
바라보다:
- 파일의 마지막 문자는 무엇입니까?그리고
- C 코드로 EOF를 표현하시겠습니까?그게 다야.
답변3
/dev/null
보내 지마 EOF
. 그냥 연결이 끊어집니다. 파일을 닫습니다. 길이가 0인 파일을 에뮬레이트합니다.
답변4
논리적으로 EOF의 개념은 I/O 핸들러에 의해 생성됩니다. EOF 신호는 일반적으로 처리되는 데이터와 관련이 없습니다.
"EOF를 보내는" 유일한 방법은 독자가 무언가를 읽어 달라는 요청에 대한 응답으로 읽을 것이 없다고 보고하도록 하는 것입니다.
Hi 함수가 EOF까지 stdin을 중계하고 echo 명령의 출력을 재생하는 데 사용되는 다음 코드를 고려하세요.
Hi() {
while IFS= read -r -d $'\n' || [[ "$REPLY" ]]; do
echo "Hi: $REPLY"
done }
Hi < <(echo Hello)
Hi: Hello
- <(명령)은 bash가 제공된 명령의 출력을 기반으로 파이프(개념적으로 파일)를 생성하도록 합니다.
- <(command)는 다음과 같이 말하면 파이프의 고유한 파일 이름으로 대체됩니다.
echo <(echo Hi)
/dev/fd/63
따라서 <(명령)은 stdout에서 파일을 생성하고 각 파일에는 데이터의 물리적 끝으로 인해 더 이상 사용할 수 있는 데이터가 없다는 것을 판독기가 알 수 있는 논리적 EOF가 있을 수 있습니다.
<() 내의 명령이 계속 실행되는 동안 파이프는 열린 상태로 유지되므로 파이프가 열린 상태로 유지됩니다. <(명령)이 완료되면 파이프의 입력 끝이 닫힙니다.
bash read 문이 EOF를 발견하면 오류 코드 1로 종료됩니다. ilkkachu에 따르면 이는 파일에서 읽을 데이터가 더 이상 없을 때 발생하기 때문에 성공적인 0바이트 시스템 read()입니다.
파일 판독기가 활성 프로세스로 남아 있는 한 시스템 read() 호출은 반환되지 않고 중단될 수 있습니다. 시간 초과로 인해 영원히 중단되는 것을 방지할 수 있습니다. 물리적 드라이브 시작 및 기타 연결이 매우 느릴 수 있습니다. 시간 초과로 인해 EOF를 가정하는 것은 느리고 오류가 발생하기 쉽습니다. 성공적인 시스템 읽기() 0바이트 = EOF.
while IFS= read -r -d $'\n' || [[ "$REPLY" ]]; do
||(논리적 OR) 테스트는 파일이 캐리지 리턴으로 끝나지 않는 경우를 처리하기 위해 존재합니다. -d에 따르면 캐리지 리턴을 읽을 때 bash read가 성공적으로 반환됩니다. 데이터를 성공적으로 읽었더라도 Bash 읽기는 0이 아닌 코드 1로 실패하기 때문에 코드 1로 실패합니다. 이는 bash가 릴레이 EOF를 읽는 방식입니다.
입력에서 출력으로 정보를 전달하는 모든 프로그램은 데이터 스트림에서 보는 정보에 반응하도록 선택할 수 있습니다.
콘솔 tty(현재 pty 또는 의사 터미널) 라인 판독기/편집기(ReadLine)는 키보드에서 읽은 여러 문자 및 이스케이프 시퀀스에 반응하여 특별한 의미를 부여합니다. 예를 들어 Control-H는 백스페이스를 수행하고 Control-D는 EOF 신호(EOT 또는 전송 종료라고 함)를 보내고 tty 자체는 열린 상태로 유지되어 다른 읽기에 대한 추가 정보를 보낼 수 있습니다.