![bashscript는 오른쪽 화살표 키를 눌렀는지 감지합니다.](https://linux55.com/image/60672/bashscript%EB%8A%94%20%EC%98%A4%EB%A5%B8%EC%AA%BD%20%ED%99%94%EC%82%B4%ED%91%9C%20%ED%82%A4%EB%A5%BC%20%EB%88%8C%EB%A0%80%EB%8A%94%EC%A7%80%20%EA%B0%90%EC%A7%80%ED%95%A9%EB%8B%88%EB%8B%A4..png)
키코드가 오른쪽 화살표 키가 아닌 경우에도 항상 true를 감지하는 이유는 무엇입니까?
stty_state=`stty -g`
stty raw; stty -echo
keycode=`dd bs=1 count=1 2>/dev/null`
stty "$stty_state"
echo $keycode
if [ "$keycode"=39 ]; then
echo "Right Arrow Key Pressed!"
fi
답변1
(아마도) 먼저 2바이트 이상을 읽었을 것입니다. $keycode
화살표 키를 누르면 스크립트에서 ESC가 됩니다.
화살표 키는 다음과 같습니다.
\x1b + some value
조건식에는 공백이 없기 때문에 항상 true로 평가됩니다.
편집: 이 진술을 업데이트하십시오.
if
명령의 종료 상태에 따라 작업 합니다 [
. 이 [
명령은 test
실제로 와 동일합니다.주문하다이것은 매우 중요한 사실입니다. 명령으로서 인수 사이에 공백이 필요합니다. 이 명령의 더 특별한 점은 마지막 매개변수로 [
필요하다는 것입니다 .]
[ EXPRESSION ]
명령은 EXPRESSION에 의해 결정된 상태로 종료됩니다. 1 또는 0,진짜또는잘못된.
이것은아니요괄호를 쓰는 이상한 방법. 다시 말해서아니요구문의 일부( if
예: C:)
if (x == 39)
통과:
if [ "$keycode"=39 ]; then
당신은 다음을 발행합니다:
[ "$keycode"=39 ]
다음으로 확장
[ \x1b=39 ]
여기서는 다음 \x1b=39
과 같이 읽습니다하나토론. 언제 test
또는[
주어졌는가하나매개변수가 false로 종료됩니다.~하지 않는 한EXPRESSION은 비어 있습니다. 이는 결코 사실이 아닙니다. $keycode
비어 있어도 결과는 =39
(비어 있지 않음/null)입니다.
그것을 보는 또 다른 방법은 다음과 같습니다.
if 0 ; then # When _command_ exit with 0.
if 1 ; then # When _command_ exit with 1.
[
자세한 내용과 vs에 대한 토론을 보려면 다음 질문과 답변을 읽어보세요 [[
.
이와 관련하여 백틱 대 백틱을 살펴볼 수도 있습니다.$( )
화살표 키가 포함된 멀티바이트 이스케이프 시퀀스:
상술 한 바와 같이:(아마도) 먼저 2바이트 이상을 읽었을 것입니다. $keycode
화살표 키를 누르면 스크립트에서 ESC가 됩니다.
화살표 및 기타 특수 키로 인해이스케이프 시퀀스시스템으로 보냅니다. 이것ESC바이트신호"여기에는 다르게 해석되어야 하는 일부 바이트가 나타납니다.". 화살표 키는 ASCII [
다음에 ASCII A
또는 입니다 B
.C
D
즉, 화살표 키를 처리할 때 3바이트를 구문 분석해야 합니다.
다음 방향으로 확인해 보세요.
{ stty_state=$(stty -g)
stty raw isig -echo
keycode=$(dd bs=8 conv=sync count=1)
stty "$stty_state"
} </dev/tty 2>/dev/null
printf %s "$keycode" | xxd
생산하다:
HEX ASCII
1b 5b 41 .[A # Up arrow
1b 5b 42 .[B # Down arrow
1b 5b 43 .[C # Right arrow
1b 5b 44 .[D # Left arrow
| | |
| | +------ ASCII A, B, C and D
| +--------- ASCII [
+------------ ASCII ESC
이것이 얼마나 이식성이 있는지는 확실하지 않지만 이와 같은 코드는 이전에 화살표 키를 캡처하는 데 사용되었습니다. 종료 하려면 누르세요 q
.
while read -rsn1 ui; do
case "$ui" in
$'\x1b') # Handle ESC sequence.
# Flush read. We account for sequences for Fx keys as
# well. 6 should suffice far more then enough.
read -rsn1 -t 0.1 tmp
if [[ "$tmp" == "[" ]]; then
read -rsn1 -t 0.1 tmp
case "$tmp" in
"A") printf "Up\n";;
"B") printf "Down\n";;
"C") printf "Right\n";;
"D") printf "Left\n";;
esac
fi
# Flush "stdin" with 0.1 sec timeout.
read -rsn5 -t 0.1
;;
# Other one byte (char) cases. Here only quit.
q) break;;
esac
done
(작은 참고로, 십진수와 16진수가 혼합된 것처럼 보이는 십진수 39에 대해서도 테스트할 예정입니다. 이스케이프 시퀀스의 첫 번째 바이트는 다음과 같습니다.ASCII 값 ESC,지금 바로소수27 및 16진수 0x1b
, 반면소수39는 16진수입니다 0x27
. )