Bash 매뉴얼 페이지에는 내장 기능에 대해 다음과 같이 나와 있습니다 read
.
파일의 끝이 발생하지 않는 한 종료 상태는 0입니다.
-e
옵션을 설정하고 다음 코드를 사용했기 때문에 최근에 이것이 나를 괴롭혔습니다 .
read -rd '' json <<EOF
{
"foo":"bar"
}
EOF
이 경우 실패한 종료가 필요한 이유를 이해하지 못합니다. 이것은 어떤 상황에서 유용합니까?
답변1
read
레코드를 읽고(기본값은 줄이지만 ksh93/bash/zsh는 -d
zsh/bash를 사용할 때 NUL도 포함하여 다른 구분 기호를 허용합니다) 전체 레코드를 읽는 한 성공을 반환합니다.
read
EOF를 찾았지만 아직 레코드 구분 기호를 만나지 않은 경우 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" ]
데이터 가 있는지 확인할 수 있습니다.
귀하의 경우에는 read
NUL 문자가 포함되어 있지 않기 때문에 입력에 레코드가 포함되어 있지 않습니다. bash
이 문서에는 NUL을 포함할 수 없습니다 . 따라서 read
전체 레코드를 성공적으로 읽지 못했기 때문에 실패합니다. json
EOF(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"에 내장된 이진 데이터나 인쇄할 수 없는 문자와 같은 특수 문자가 있어야 하는 경우를 제외하고는 텍스트가 따옴표 안에 있기 때문에 필요하지 않습니다. 따라서 파일을 데이터 소스로 사용하면 분명히 작동하지 않습니다.