Обычно bash используется для неинтерактивного выполнения скриптов. А что делать, если хочется чего-то интерактивного?

Можно использовать оператор read. По умолчанию он читает ту херню, которую пользователь пишет на клавиатуре. Ну, не всю херню.

В общем, тут возникают проблемы. Даже не так. ТУТ ВОЗНИКАЮТ ПРОБЛЕМЫ.

Проблем несколько, и они нихрена не решаются простыми способами:

  1. Только простые клавиши генерят одиночные коды типа буквы, цифры, печатные символы.
  2. Стрелки, HOME, END… и особенно функциональные клавиши (F1-F12) генерят многобайтные коды.
  3. Клавиши TAB ENTER SPACE вообще нихрена не выдают.
  4. Коды нажатых клавиш зависят от терминала, который у вас эмулируется.
  5. Очень много клавиш используется в качестве "горячих", поэтому их обработка производится раньше, чем их обработает bash.
Tagd Tagd
Tagd Tagd
Bash Master
Задать вопрос
В общем - если вы умный человек - не используйте bash для обработки функциональных клавиш.

А если похожи на меня - приведу функцию, которая помогает минимизировать проблемы.

Поскольку не все клавиши генерят печатные коды, я не придумал ничего более умного, чем конвертнуть коды в hex-последовательность. Поверьте, работать со строкой в 10 символов проще, чем с управляющими символами.

Понятней.

Программа более-менее обрабатывает совместное нажатие CTRL+, ALT+. Не обрабатывает нажатия нескольких клавиш.

#!/bin/bash

function GET_KEY(){
  declare K1 K2 K=
  declare -i i
  read -rsn1 K1;read -rsn4 -t 0.001 K2
  if [[ "$K1" != $'\x1b' ]];then
    K2=
  fi
  K1="${K1}${K2}"
  i=${#K1}
  while ((i--));do
    printf -v K2 "%02X" \"${K1:$i:1}\"
    K=${K2}${K} 
  done
  printf "%s" $K
}
clear
echo "TERMINAL="$TERM
KEY=1
while [ "$KEY" != "" ];do
  KEY=$(GET_KEY)
  echo $KEY
#  echo -e "\x$KEY"
done

сохраните в файл key2hex.sh

chmod +x ./key2hex.sh
./key2hex.sh

Под закрытым текстом объяснения для начинающих.

Поскольку программа простая - сильно комментировать не буду.

read -rsn1 K1;read -rsn4 -t 0.001 K2 считывает 1 символ, потом возможно еще 4, но с малым временем ожидания. Если символ многобайтный - в буфере он уже есть.

Если символ начинается не с кода 1b (ESC) он должен быть однобайтным. ${#K1} -число символов в строке.

Далее в цикле while ((i–));do посимвольно преобразуем строку в hex, накапливая в переменной K

echo -e "\x$KEY" команда перевода hex в char привожу для примера.

Для прикола попробуйте выполнить программу в разных терминалах (LxTerminal и tty1) и посмотреть на F5.

Поясню, в tty1 можно перейти из GUI CTRL+ALT+F1, а вернуться обратно обычно ALT+F7

Ну, или не F7. посмотреть, куда возвращаться можно командой w . Даже маленькие разберутся.

В общем, терминал(ы) - штука сложная. И вот только теперь я начал немного понимать, нахрена нужна библиотека ncurses.

help read printf man w printf