EOF가 발생할 때 출구 1을 "읽는" 목적은 무엇입니까?

EOF가 발생할 때 출구 1을 "읽는" 목적은 무엇입니까?

Bash 매뉴얼 페이지에는 내장 기능에 대해 다음과 같이 나와 있습니다 read.

파일의 끝이 발생하지 않는 한 종료 상태는 0입니다.

-e옵션을 설정하고 다음 코드를 사용했기 때문에 최근에 이것이 나를 괴롭혔습니다 .

read -rd '' json <<EOF
{
    "foo":"bar"
}
EOF

이 경우 실패한 종료가 필요한 이유를 이해하지 못합니다. 이것은 어떤 상황에서 유용합니까?

답변1

read레코드를 읽고(기본값은 줄이지만 ksh93/bash/zsh는 -dzsh/bash를 사용할 때 NUL도 포함하여 다른 구분 기호를 허용합니다) 전체 레코드를 읽는 한 성공을 반환합니다.

readEOF를 찾았지만 아직 레코드 구분 기호를 만나지 않은 경우 0이 아닌 값을 반환합니다.

이를 통해 다음과 같은 작업을 수행할 수 있습니다.

while IFS= read -r line; do
  ...
done < text-file

아니면 zsh/bash를 사용하세요

while IFS= read -rd '' nul_delimited_record; do
  ...
done < null-delimited-list

마지막 레코드를 읽은 후 루프가 종료됩니다.

다음을 사용하여 마지막으로 완료된 기록 이후에 더 많은 [ -n "$nul_delimited_record" ]데이터 가 있는지 확인할 수 있습니다.

귀하의 경우에는 readNUL 문자가 포함되어 있지 않기 때문에 입력에 레코드가 포함되어 있지 않습니다. bash이 문서에는 NUL을 포함할 수 없습니다 . 따라서 read전체 레코드를 성공적으로 읽지 못했기 때문에 실패합니다. jsonEOF(IFS 처리 후)까지 읽은 내용을 변수에 계속 저장합니다 .

어쨌든 read설정하지 않고 사용하는 것은 거의 의미가 없습니다 $IFS.

자세한 내용은 다음을 참조하세요."IFS=read-r-line" 이해.

답변2

이것이 내가 나 자신을 사용하지 않는 이유 중 하나이다 set -e.

이제 주어진 EOL 구분 기호 없이 EOF에 도달하면 읽기가 1을 반환한다는 것을 알았으므로 다음 중 하나를 수행할 수 있습니다.

# depending on the contents of the input, it's an error
# if no data was read:
IFS= read -rd '' json <<EOF || [[ -n $json ]]
...
EOF

# or, you don't care at all how much data was read
IFS= read -rd '' json <<EOF || :
...
EOF

답변3

기본적으로 읽기 명령은 사용자 입력의 행을 대상으로 하지만 파일에서 작동하려면 줄 끝 구분 기호에 도달하기 전에 파일의 데이터가 모두 소모되는 시기를 감지할 수 있어야 합니다.

귀하의 예에서 EOF라는 단어는 리디렉션 연산자의 인라인 텍스트를 구분하는 데 사용됩니다.<<그리고 문서에 언급된 "파일 끝" 표시를 읽는 것과는 아무런 관련이 없습니다. 단, 데이터가 마지막 줄의 개행 문자(닫는 중괄호 포함) 다음에 끝난다는 신호를 인터프리터에 보내는 것 외에는 없습니다. 물론, 그 구성은 완전한 데이터를 갖고 있고 파일로부터 온 것이 아니기 때문에 파일의 끝이 데이터의 갑작스러운 끝이 되는 상황은 있을 수 없습니다.

따라서 읽기 매뉴얼 페이지의 지침은 여기서는 실제로 적용되지 않으며, 끝을 eof로 표시할 수 있는 파일이나 데이터 소스에서 읽을 때만(예: 사용자가 [Ctrl-D]를 누르거나 끝에 도달한 경우) 데이터를 읽을 수 있습니다. 파이프라인의 다른 명령에서 옵니다).

이는 d 및 r 옵션의 특별한 동작과 결합됩니다. -d는 줄 끝과 관계없이 가능한 모든 것을 읽을 수 있게 하고 (여기서는 필요하다고 생각합니다) -t는 읽기에서 백슬래시 이스케이프 문자를 무시하도록 합니다(텍스트에는 존재하지 않음). "bar"에 내장된 이진 데이터나 인쇄할 수 없는 문자와 같은 특수 문자가 있어야 하는 경우를 제외하고는 텍스트가 따옴표 안에 있기 때문에 필요하지 않습니다. 따라서 파일을 데이터 소스로 사용하면 분명히 작동하지 않습니다.

관련 정보