읽기에 대한 무음 옵션이 무시됩니까?

읽기에 대한 무음 옵션이 무시됩니까?

특정 키를 누를 때까지 bash 쉘 스크립트에서 루프를 실행하고 있습니다(Ctrl-C는 항상 나에게 잔인합니다). -s 옵션을 사용했지만 read터미널에는 단일 문자가 표시됩니다. -s 옵션이 read예상한 대로 작동하지 않는 이유는 무엇입니까?

until read -s -n 1 -t 0.01; do 
    echo -n "."
    sleep .5    # actual script code goes here
    done 
echo 

답변1

sleep .5나는 이것이 실행하는 동안이 아니라 실행하는 동안 키를 눌렀기 때문이라고 확신합니다 read.

더 자세히 설명하면 실행되는 동안 read -s -n 1 -t 0.01터미널을 0.01초 동안 noecho 모드로 전환한 다음 시간이 초과되고 에코가 다시 켜집니다. 그 0.01초 이내에 문자를 입력하면 해당 문자가 반향되지는 않지만 해당 창을 놓칠 수 있습니다. 대신 sleep .5런타임에 입력하면 다시 에코됩니다. 그런 다음 0.5초 후에 다시 실행하고 read에코를 끄고(너무 늦었습니다!) 사전 입력 버퍼에서 문자를 읽은 다음 마지막으로 에코를 다시 켭니다.

(참고: 이 echo명령과 echo 터미널 모드는 둘 다 터미널에 인쇄하는 것과 관련된다는 점을 제외하면 직접적인 관련이 없습니다.)

read -s해결 방법: 에코를 끌 것으로 기대하지 말고 stty -echo처음에 한 번 사용하고 stty echo마지막에 다시 켜십시오. Billy 삼촌이 주석에서 지적했듯이 trap어떤 이유로(예: Control-C) 스크립트가 비정상적으로 종료되면 터미널 설정이 정상으로 돌아가도록 a를 추가하는 것도 현명합니다.

trap 'stty echo' EXIT    # If script exits abnormally, fix terminal
stty -echo    # turn off echo
until read -n 1 -t 0.01; do
    echo -n "."
    sleep .5
done
echo
stty echo    # turn echo back on

( trap나중에 삭제할 수 있지만 문제가 되지 않습니다. 터미널을 원래대로 설정하는 것은 어쨌든 매우 안전한 작업입니다.)

sleep편집: ilkkachu가 의견에서 지적했듯이 완전히 제거 하고 더 긴 시간 초과를 사용하는 것이 좋습니다 read. 그러면 키를 누를 때 키 누르기를 알아차리기까지 0.5초를 기다리지 않습니다. 더 긴 시간 초과를 사용할 수도 있습니다. 매번 개별적으로 에코를 끄는 stty -echo대신 계속해서 에코를 끄는 방법을 사용하겠습니다 .read -s

trap 'stty echo' EXIT
stty -echo    # turn off echo
until read -n 1 -t 3600; do    # 1 hour timeout, 'cause why not
    echo -n "."
done
echo
stty echo    # turn echo back on

루프가 필요하지 않으면 완전히 제거할 수 있습니다( 이 경우에는 read -s제대로 작동합니다 ).

read -s -n 1

관련 정보