특정 키를 누를 때까지 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