TGViewer
Bash Days | Linux | DevOps Bash Days | Linux | DevOps @bashdays · 23.6K subscribers
Post #579 9.71K
Обычно bash используется для неинтерактивного выполнения скриптов. А что делать, если хочется чего-то интерактивного?
ㅤ
Можно использовать оператор read. По умолчанию он читает ту херню, которую пользователь пишет на клавиатуре. Ну, не всю херню.

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

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

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

В общем - если вы умный человек - не используйте 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


tags: #bash © by Tagd Tagd
—
🔔 @bashdays➡️ @gitgate
More from @bashdays
  1. Sep 29, 2026Самый жаркий холивар в команде — это не systemd, а какие заказать роллы на всю команду. Од…
  2. Sep 24, 2026Post #1565
  3. Sep 23, 2026Здрасти приехали, решил я в кой-то веке воспользоваться услугами Codex, создал аккаунт, по…
  4. Sep 22, 2026Всем привет, с вами TagdTagd. Сегодня опять поднимем тему архивов, но немного с другой сто…
  5. Sep 15, 2026Всем привет, с вами TagdTagd. И это вторая часть. Практическая. С первой частью можешь озн…
  6. Sep 11, 2026🤖 DevOps в эпоху AI трансформации: что работает уже сейчас! 17 сентября Сбер собирает Dev…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →