Ви (ймовірно) прочитали перший із двох байтів. $keycodeу вашому сценарії буде ESC, коли натискається клавіша зі стрілкою.
Клавіші зі стрілками можуть бути:
\x1b + some value
Він завжди оцінюється як істинний через відсутність пропусків у умовному вираженні.
Редагувати: оновлення цього твердження.
Ваша ifфункція працює над статусом виходу [команди. [Команда еквівалентна test. Те, що це команда, є дуже важливим фактом. Як команда, вона вимагає пробілів між аргументами. Далі [команда особлива тим, що вона вимагає ]в якості останнього аргументу.
[ EXPRESSION ]
Команда виходить зі статусом, визначеним EXPRESSION. 1 або 0, правда чи хибність .
Це не екзотичний спосіб написання дужок. Іншими словами, це не є частиною ifсинтаксису, як, наприклад, у C:
if (x == 39)
Автор:
if [ "$keycode"=39 ]; then
ви видаєте:
[ "$keycode"=39 ]
який розширюється до
[ \x1b=39 ]
тут \x1b=39читається як один аргумент. Коли testабо [дається один аргумент, він закінчується помилковим, лише якщо EXPRESSION є нульовим - чого ніколи не буде. Навіть якщо він $keycodeбув порожнім, це призведе до =39(що не є нульовим / порожнім).
Ще один спосіб поглянути на це - сказати:
if 0 ; then # When _command_ exit with 0.
if 1 ; then # When _command_ exit with 1.
Прочитайте ці запитання та відповіді для більш детальної інформації - а також обговорення щодо [vs [[:
У цьому плані ви також можете дослідити тики `` vs $( )
Послідовність втечі багатобайтових клавіш зі стрілками:
Як згадувалося вгорі: ви (швидше за все) прочитали перший із двох байтів. $keycodeу вашому сценарії буде ESC, коли натискається клавіша зі стрілкою.
Стрілка та інші спеціальні клавіші призводять до того, що послідовності втечі повинні бути відправлені в систему. В ESC байтові сигнали , які «тут приходить кілька байтів , які повинні бути витлумачені по- різному» . Що стосується клавіш зі стрілками , які будуть ASCII - [слідують ASCII A, B, Cабо D.
Іншими словами, вам потрібно розібрати три байти під час роботи зі стрілками.
Ви можете спробувати щось у цьому напрямку, щоб перевірити:
{ 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
(Як другорядне зауваження, ви також (маєте намір) протестувати проти десяткової 39 - це схоже на змішування між десятковою та шістнадцятковою. Перший байт у послідовності відхилення - це значення ASCII ESC , яке становить десятковий 27 і шістнадцятковий 0x1b, а десятковий 39 - шістнадцятковий 0x27. )