Чтение нажатий клавиш в оболочке с использованием сигналов trap и Unix

У меня возникли проблемы с пониманием цели trap и множественных stty вызовов в нижеприведенном фрагменте.

Я надеялся, что кто-то может дать мне краткое изложение того, что происходит.

 getkey() { local stty="$(stty -g)" trap "stty $stty; trap SIGINT; return 128" SIGINT stty cbreak -echo local key while true; do key=$(dd count=1 2>/dev/null) || return $? if [ -z "$1" ] || [[ "$key" == [$1] ]]; then break fi done stty $stty echo "$key" return 0 } 

  • Чтение двоичного файла в виде массива байтов или 16 или 32 бит с использованием сценария оболочки
  • Выполнение «вилочной бомбы» безопасно
  • Добавить 0 в середине имени файла
  • BASH как сохранить вывод rm с меткой времени?
  • Как rsync файлы между двумя пультами?
  • Как Linux работает со сценариями оболочки?
  • Сценарий оболочки декодирования Url
  • set -u использование не работает как ожидалось
  • One Solution collect form web for “Чтение нажатий клавиш в оболочке с использованием сигналов trap и Unix”

     local stty="$(stty -g)" 

    Сохраните текущие настройки терминала. stty $stty , который выполняется как при нормальной работе функции, так и в SIGINT, восстанавливает эти настройки.

     trap "stty $stty; trap SIGINT; return 128" SIGINT 

    Если функция прервана SIGINT (сигнал, посланный нажатием Ctrl + C ), восстановите настройки терминала и верните 128. (Почему 128? Мне интересно. Обычно статус выхода по сигналу будет 128 + номер сигнала.)

     stty cbreak -echo 

    Отключите функциональные возможности редактирования терминала (стирание символа / слова / строки) и отключите эхо символов при их вводе.

      key=$(dd count=1 2>/dev/null) || return $? 

    Прочитайте до 512 байт от терминала ( count – это количество блоков, а размер блока по умолчанию – 512 байт). Это немного странно: я думаю, что цель состояла в том, чтобы прочитать один байт. Поскольку dd будет возвращаться, как только будет доступен хотя бы один байт, это на практике вернет один байт, если пользователь печатает, но если программа подает нажатия клавиш или система медленная, это может читать больше байтов. Код имеет то преимущество, что, если пользователь набирает многобайтовый символ, все байты, составляющие символ, скорее всего (но не гарантированы) должны быть прочитаны в итерации цикла.

    Если dd возвращает ненулевой статус, это указывает на ошибку чтения или сигнал; функция немедленно возвращается. Настройки терминала не восстанавливаются, что является ошибкой, хотя большую часть времени ошибка была либо в том, что пользователь нажал Ctrl + C , и в этом случае настройки терминала восстанавливаются, либо терминал исчезает, и в этом случае точка спорная.

      if [ -z "$1" ] || [[ "$key" == [$1] ]]; then break fi 

    Выйдите из цикла, если байт (ы), который был прочитан, является одним из символов в аргументе функции. Если аргумент пуст, любой символ завершает цикл. Аргумент не является точно списком символов, это в синтаксисе набора символов подстановки : начальный ^ или ! инвертирует множество, знак минус в большинстве позиций анализируется как диапазон (например, 0-9 ), [:…:] и [.….] обозначают классы символов и символы сопоставления соответственно, а обратная косая черта цитирует следующий \ , [ , ] или - .

    Interesting Posts

    Как настроить почтовую команду для чтения Maildir вместо стандартного mbox на OpenBSD?

    Как сделать ключи доступа GPG доступными через SSH?

    Как экспортировать хранилище ключей bks на debased 7.9 wheezy

    CrunchBang & Openbox: нет реакции на нажатие кнопки питания ноутбука

    Как я могу печатать только переменные, определенные внутри моего сценария оболочки?

    Как установить новый пароль из bash?

    Как найти и заменить строку без использования команды Sed?

    Как читать определенные строки после поиска текста?

    отображение страницы 2 и т. д. многостраничного tiff

    Извлеките список .zip-файлов в один новый каталог каждый, имя каталога, которое будет взято из имени zip-файла

    Блокировка веб-сайтов по дням и часам с использованием Iptables в OpenWRT

    Неспособная игра для создания пользователя, не устанавливающего пароль

    Переход на виртуальный терминал медленный

    переменная curl outfile не работает в скрипте bash

    Возможно выполнить команду pipe с помощью su через ssh

    Linux и Unix - лучшая ОС в мире.