Как предотвратить отображение нежелательных последовательностей клавиш ANSI во время чтения в сценарии bash/ash?

Я пытаюсь создать скрипт, который обрабатывает клавиши со стрелками в очень ограниченной системе с занятым пеплом и совсем немного другим. Нет, например. У меня есть кое-что, что в основном работает, но иногда некоторые экранирующие последовательности ANSI появляются на экране. Похоже, это происходит чаще всего, когда срабатывает автоматическое повторение клавиш, но также и тогда, когда необходимо выполнить более сложную обработку, прежде чем читать следующую клавишу. Это в основном хорошо на моем ноутбуке, который работает быстрее, чем моя целевая система, но если я иногда удерживаю клавиши со стрелками, такие как ^[[B появляется на экране. Как это проходит безмолвные чтения?

Я явно не обращался с HOME и END, чтобы ^[OH и ^[OF проходили чаще. Это заставляет меня думать, что, возможно, они просачиваются в течение периода ожидания, но я действительно не знаю.

В любом случае, есть ли какая-нибудь хитрость с трубкой или подоболочкой, которая может содержать побег?

E=$(printf "\033")
NL='
'
# Works in bash, ash without stty but takes a sec for ESC key (not ESC sequence)
# But even with nothing but q key checks in the loop it still occasionally
# spams the screen with ^[[B etc if I hold arrow keys down for auto-repeat.
while true; do
  IFSBAK=$IFS ; IFS=
  read -rsn1 _KEY
  case "${_KEY}" in
    "${E}") _K=""; read -sn2 -t1 _K; _KEY="${E}${_K}";
      case "${_K}" in
    "[A"|"[B"|"[C"|"[D"|"") ;;
    "OP"|"OQ"|"OR"|"OS") ;;
    *) _K=""; read -n1 -t1 _K; _KEY="${_KEY}${_K}" ;;
      esac
  ;;  "") _KEY="NL"
  ;;
  esac
  IFS=$IFSBAK ; IFSBAK=

  case "$_KEY" in
    "${E}" | q )
      break;;
  esac
done

1 ответ

Решение

Вопрос в том

Как это проходит безмолвные чтения?

Это связано с тем, что скрипт переключает терминал во вход / выход из режимов, используемых для чтения без вывода сообщений (no-echo), а ваши ключи отражаются оболочкой, когда он не ожидает ввода. Вы можете улучшить это, используя stty, чтобы отключить эхо во время работы скрипта (и восстановить эхо при выходе).

Другие вопросы по тегам