stdin
문자열 구분 기호가 발견될 때부터 읽기를 시작하고 싶습니다 MARKER=$'\0'"BRISH_MARKER"
. 나는 시도했다:
❯ unset br ; print -rn -- hi${MARKER}world | { IFS= read -d "$MARKER" -r br ; cat -v } ; echo ; typeset -p br
이것은 만든다:
BRISH_MARKERworld
typeset br=hi
따라서 read
주어진 구분 기호의 첫 번째 문자만 사용됩니다 \0
. 전체 문자열을 사용하고 싶습니다. 이 목표를 어떻게 달성할 수 있나요?
제가 해결하려는 문제는 지속적으로 데이터 스트림을 zsh 프로세스에 공급하는 프로세스가 있고 구분 기호를 사용하여 데이터를 다른 값으로 분할해야 한다는 것입니다. 처음에는 그냥 사용했는데 \0
포함된 값을 사용할 수 없어서 \0
현재 MARKER
.
답변1
예 read -d
단일 문자 구분 기호에만 작동합니다. ( 단일 문자 구분 기호에만 작동합니다. bash
)ksh93
바이트분리 기호).
구분 기호를 읽는다는 것은 읽지 않도록 하기 위해 한 번에 한 바이트씩 읽어야 함을 의미합니다(특히 파이프와 같이 탐색할 수 없는 입력의 경우).과거구분 기호로 인해 비효율적입니다.
대신 로깅을 사용하는 것이 좋습니다 length:value
.
write-record() {
set -o localoptions +o multibyte
print -rn -- "$#1:$1"
}
read-record() {
set -o localoptions +o multibyte
local len
# note that in current versions of zsh, read -k0 (for empty records)
# returns a non-zero exit status.
eval "$1="
IFS= read -rd: len || return
((len == 0)) || read -u0 -k "$len" "$1"
}
( multibyte
해당 길이(바이트)를 로컬에서 비활성화하고 여기에서 쓸모 없는 문자 인코딩/디코딩을 피하십시오.)
예를 들면 다음과 같습니다.
$ (write-record $'é\0x'; write-record $'foo\0MARKER') | { read-record a && read-record b; printf "<%q>\n" "$a" "$b"; }
<é$'\0'x>
<foo$'\0'MARKER>