내장된 read 명령 대신 이 사용자 정의 read_char 함수를 사용해야 하는 이유가 있나요?

내장된 read 명령 대신 이 사용자 정의 read_char 함수를 사용해야 하는 이유가 있나요?

나는 bash와 Linux를 잘 못합니다. 스크립트를 읽다가 다음 함수를 찾았습니다.

get_char()
{
    SAVEDSTTY=`stty -g`
    stty -echo
    stty cbreak
    dd if=/dev/tty bs=1 count=1 2> /dev/null
    stty -raw
    stty echo
    stty $SAVEDSTTY
}

기본적으로 구현하는 데 사용됩니다.계속하려면 아무 키나 누르세요.이와 같은 기능.

echo "Press any key to continue!"
char=`get_char`

read이를 달성하기 위해 내장 명령을 사용할 수 있다는 것을 알고 있습니다 . 예를 들어:

read -rsn1 -p "Press any key to continue"

내장 read명령 대신 이 기능을 사용하는 이유가 있나요?

답변1

문제의 함수는 get_char멀티바이트 문자에 대한 키를 생성하는 데 문제가 있으며 실제로 stty표준 입력에서 작동하지만 [1] 에서 dd읽습니다 /dev/tty. 따라서 비교를 위해 "고정" 및 단순화된 버전을 사용하겠습니다.

get_char(){
  _g=$(stty -g); stty raw -echo; dd count=1 2>/dev/null; stty "$_g"
}

k=$(get_char)와 사이의 몇 가지 차이점은 다음 read -rsn1 k과 같습니다.

  1. 전자는 이식 가능합니다. dash, bash, 등에서 zsh동일한 방식으로 작동 하며 read -rsn1에서만 bash작동합니다 ksh.

  2. F1유사한 키를 누르면 선행(Esc)을 먹고 나중에 사용하기 위해 남겨 두는 대신 k=$(get_char)해당 키에 의해 생성된 전체 이스케이프 문자( )가 설정됩니다 . k둘 이상의 문자를 생성하는 모든 키에도 동일한 내용이 적용됩니다.F1^[OP^[OP

  3. Ctrl-C( VINTR), Ctrl-Q( VQUIT) 또는 Ctrl-Z( VSUSP)는 원래 제어 문자( , 또는 )를 k=$(get_char)설정하여 사용 시 스크립트를 중단하거나 일시 중지합니다 [2].k\x03\x11\x1aread -rsn1


[1] 제어 tty에서 읽어야 하는 경우 간단히 다음과 같이 사용할 수 있습니다.k=$(get_char </dev/tty)

[2] read -rsn1스크립트가 일시 중지되었다 Ctrl-Z가 다시 시작되면 tty 설정이 복원되지 않습니다 fg.

줄 편집기가 있는 셸에서 사용되는 경우의 예 - 그 자체로 tty 설정이 엉망이 됩니다.

$ bash -c 'read -rsn1 foo; echo "{$foo}"'
<Ctrl-Z>
[4]+  Stopped                 bash -c 'read -rsn1 foo; echo "{$foo}"'
$ fg
bash -c 'read -rsn1 foo; echo "{$foo}"'
f<Enter>
{f}
$
$ bash -c 'read -rsn1 foo; echo "{$foo}"'
<Ctrl-Z>
[4]+  Stopped                 bash -c 'read -rsn1 foo; echo "{$foo}"'
$ fg
bash -c 'read -rsn1 foo; echo "{$foo}"'
foo<Enter>
{f}
$ oo
bash: oo: command not found

또는 tty 설정을 방해하지 않는 쉘에서 사용되는 경우(예 dash: ):

$ bash -c 'read -rsn1 foo; echo "{$foo}"'
<Ctrl-Z>
[1] + Stopped                    bash -c "read -rsn1 foo; echo \"{\$foo}\""
$ <Blindly type f, g, Enter>bash -c "read -rsn1 foo; echo \"{\$foo}\""
{e}
$

관련 정보