빈 문자열을 인수로 사용할 때 "read" 셸 명령의 "-d" 옵션은 무엇을 합니까?

빈 문자열을 인수로 사용할 때 "read" 셸 명령의 "-d" 옵션은 무엇을 합니까?

내가 읽을 때이 답변, 작성자는 이 명령을 사용하여 구분 기호의 결과를 변수에 넣습니다.

read -r -d '' VAR <<'EOF'
abc'asdf"
$(dont-execute-this)
foo"bar"''
EOF

이 옵션에 대해 조금 혼란스러워요 -d. 이 명령에 대한 도움말 텍스트에서 read:

-d delim
continue until the first character of DELIM is read, rather than newline

따라서 빈 문자열을 전달하면 -d다음을 의미합니다.첫 번째 빈 문자열까지 읽기. 무슨 뜻이에요? 저자는 -d ''NUL 문자열을 구분 기호로 사용하는 방법 에 대한 답변 아래에 댓글을 달았습니다 . 이것이 사실입니까(빈 문자열은 NUL 문자열을 의미함)? -d '\0'등 을 사용하지 않는 이유는 무엇입니까 -d '\x0'?

답변1

대부분의 경우 이는 정확히 말하는 내용을 의미합니다. 예를 들면 다음과 같습니다.

$ 읽기 -d .변수 에코; "읽기: '$var'"
부자.
읽기: 'foo'

읽기는 에 즉시 끝났고 .거기에서 Enter 키를 누르지 않았습니다.

그런데 read -d ''상황이 좀 특이해서온라인 참조 설명서에 따르면:

-d delim
delim의 첫 번째 문자는 개행 문자가 아닌 입력 행을 종료하는 데 사용됩니다.delim이 빈 문자열인 경우 read는 NUL 문자를 읽을 때 줄을 종료합니다.

\0표현의 NUL 바이트 printf이므로 예를 들면 다음과 같습니다.

$ printf 'foo\0bar\0' | while read -d '' var; do echo "read: '$var'"; done
read: 'foo'
read: 'bar'

귀하의 예에서는 read -d ''개행 문자가 구분 기호가 되는 것을 방지하기 위해 한 번에 한 줄을 읽는 대신 한 번에 여러 줄의 문자열을 읽을 수 있도록 합니다.


일부 이전 버전의 문서에서는 이 동작을 명시적으로 언급하지 않은 것 같습니다 -d ''. 이 동작은 원래 Bash가 C에서 문자열을 저장하는 방식(후행 NUL 바이트 포함)과 우연히 일치했을 수 있습니다. 문자열은 foo로 저장되고 foo\0, 빈 문자열은 로 저장됩니다 \0. 따라서 구현 시 주의를 기울이지 않고 메모리의 첫 번째 바이트만 선택하는 경우 \0NUL을 빈 문자열의 첫 번째 바이트로 처리합니다.

질문을 더주의 깊게 다시 읽으면서 다음과 같이 언급했습니다.

저자는 답변 아래에 이것이 다음을 -d ''사용하는 것을 의미한다고 언급했습니다.NUL 문자열구분 기호로.

이것은 완전히 정확하지 않습니다. 빈 문자열(POSIX 용어로)은 내용이 포함되지 않은 길이가 0인 문자열인 빈 문자열을 의미합니다. 이는 다음과 관련이 있습니다.널 바이트, 이는 이진 값이 0(*)인 단일 바이트입니다 . 빈 문자열을 구분 기호로 사용하면 거의 모든 위치에서 찾을 수 있습니다. 쉘에서는 이것이 가능하지 않다고 생각합니다. 그러나 예를 들어 Perl에서는 다음과 같이 문자열을 분할하는 것이 가능합니다.

$ perl -le 'print join ":", split "", "foobar";'
f:o:o:b:a:r

read -d ''NUL 사용바이트구분 기호로.

(*그리고특징 0, 틀림없이. )

-d '\0'등 을 사용하지 않는 이유는 무엇입니까 -d '\x0'?

좋은 질문이네요. Stéphane이 언급했듯이 처음에 ksh93은 이를 read -d지원하지 않았 read -d ''으며 백슬래시 이스케이프를 지원하도록 변경하면 원래 버전과 호환되지 않습니다. 하지만 당신은할 수 있는원하는 경우 계속 사용할 수 있습니다 (유사한 탭 등과 read -d $'\0'함께 ). Bash는 문자열에서 NUL 바이트를 지원하지 않기 때문에 $'\t'뒤에서는 Bash와 동일합니다 . -d ''Zsh는 그렇지만 -d ''-d $'\0'.

답변2

파일의 문자로서 ASCII 0의 특성을 지적하기 위한 것입니다. Expect(내가 가장 좋아하는 도구!)는 null 값을 읽고 일치시키기 위한 특별한 규정을 만들어야 합니다.

관련 정보