개행 문자를 read
캡처 하거나 끊는 데 사용할 수 있는 것이 있나요?\n
\012
테스트 기능을 정의합니다.
f() { read -rd '' -n1 -p "Enter a character: " char &&
printf "\nYou entered: %q\n" "$char"; }
이 기능을 실행하려면 다음을 누르세요 Enter.
$ f;
Enter a character:
You entered: ''
음. 이는 빈 문자열입니다.
예상되는 출력을 얻으려면 어떻게 해야 합니까?
$ f;
Enter a character:
You entered: $'\012'
$
^D
또는 \004
.
할 수 없다면 read
해결책은 무엇입니까?
답변1
1개의 문자를 읽으려면 -N
항상 1개의 문자를 읽고 $IFS
처리를 수행하지 않는 대신 사용하십시오.
read -rN1 var
read -rn1
최대 한 문자까지 레코드를 읽고 계속 처리합니다 $IFS
(새 줄이 기본값이므로 $IFS
NUL로 구분된 레코드를 읽어도 빈 결과가 나오는 이유를 설명합니다). 이를 사용하여 읽는 레코드의 길이를 제한할 수 있습니다.
귀하의 경우 NUL로 구분된 레코드( 사용 -d ''
)를 사용하면 변수에 NUL 문자를 저장할 수 없는 것과 동일하게 작동하므로 IFS= read -d '' -rn1 var
비어 있는 상태로 유지되고 0이 아닌 종료 상태를 반환합니다.bash
printf '\0' | read -rN1 var
$var
NUL을 포함한 임의의 문자를 읽으려면 zsh
다음 구문을 대신 사용하여 셸을 사용할 수 있습니다.
read -k1 'var?Enter a character: '
(필요없습니다 -r
. IFS=
하지만 꼭 read -k
읽어 주세요.터미널에서( k
는열쇠; zsh 옵션은 -k
bash 또는 심지어 ksh93보다 -N
수십 년 더 오래 되었습니다. 표준 입력에서 읽으려면 read -u0 -k1
)을 사용하십시오.
예( Ctrl+Space여기서 NUL 문자를 입력하세요):
$ read -k1 'var?Enter a character: '
Enter a character: ^@
$ printf '%q\n' $var
$'\0'
읽을 수 있으니 참고하세요특징, read
여러 바이트를 읽어야 할 수도 있습니다. 입력이 멀티바이트 문자의 첫 번째 바이트로 시작하면 적어도 1바이트를 더 읽게 됩니다. 따라서 $var
입력에 유효한 시퀀스를 형성하지 않는 바이트 시퀀스가 포함되어 있으면 쉘이 고려하는 내용이 포함될 수 있습니다. 1자보다 길어야 합니다.
예를 들어 UTF-8 로케일에서는 다음과 같습니다.
$ printf '\xfc\x80\x80\x80\x80XYZ' | bash -c 'read -rN1 a; printf "<%q>\n" "$a" "${#a}"; wc -c'
<$'\374\200\200\200\200X'>
<6>
2
$ printf '\xfc\x80\x80\x80\x80XYZ' | zsh -c 'read -u0 -k1 a; printf "<%q>\n" $a $#a; wc -c'
<$'\374'$'\200'$'\200'$'\200'$'\200'X>
<6>
2
UTF-8에서 0xFC는 6바이트 긴 문자의 첫 번째 바이트이고, 나머지 5바이트는 비트 8이 설정되고 비트 7은 설정되지 않았음을 의미하지만 우리는 4만 제공했습니다. 문자의 끝을 찾기 위해 read
추가 정보를 계속 읽으면 유효한 문자를 형성하지 않는 5바이트가 되고 각 바이트는 결국 하나의 문자로 계산됩니다.X
$var
답변2
bash
내장 기능은 read
다음을 수행할 수 있습니다.
read -rd $'\0' -p ... -n 1
printf '\nYou typed ASCII %02x\n' "'$REPLY"
(이 코드는 멀티바이트 문자에서는 작동하지 않습니다.)
나는 당신처럼 내가 읽은 내용을 변수에 넣지 않았다는 점에 유의하십시오 char
. 이는 IFS 에서 문자를 제거하기 때문입니다 char
. 표준 IFS를 사용하면 공백, 탭 및 줄 바꿈을 구별할 수 없습니다.