Почему консоль иногда требует сброса после CTRL + C

9

Некоторые инструменты интерфейса командной строки возвращают сломанную консоль при отмене с помощью CTRL+C. Иногда текст невидим, или возникают графические проблемы, пока я не выполню команду reset.

(Я использую bash, но ожидаю, что он не зависит от оболочки.)

У этого эффекта есть имя? Что вызывает это, и как программисты могут предотвратить это в инструментах? Есть ли стратегия, как эта проблема решается на основных языках программирования?

Джонас Стейн
источник
stty saneдля седых бород
Торбьерн Равн Андерсен

Ответы:

14

Консоли иногда требуется reset(1) (или какая-то stty(1)команда), потому что состояние псевдотерминала не изменяется, когда завершается какой-то процесс (например, программа, запущенная вашей оболочкой).

Читайте tty демистифицирован .

(Я считаю обработку псевдо-терминалов и псевдотоней самой сложной частью Linux)

Есть ли стратегия, как эта проблема решается на основных языках программирования?

Хорошо работающая программа, работающая с терминалом и изменяющая его режим или линейную дисциплину, должна стараться избегать сбоев и выполнять соответствующие вызовы (см. Termios (3) ), чтобы перевести терминал в правильное состояние. Кстати, библиотеки, такие как ncurses или readline , полезны (но вам нужно правильно вызывать их процедуры очистки).

См. Сигнал (7) и безопасность сигнала (7) . Избегать сбоев в вашем коде сложно. Читайте о неопределенном поведении .

Несовершенный обходной путь может заключаться в определении функции оболочки, которая выполняет вашу программу, а затем выполняет reset(что иногда может быть неуместным).

Василий Старынкевич
источник
Этот обходной путь не велик; иногда resetможет привести к отличным sttyнастройкам от оригинальных.
Боб
Да, спасибо за указание на это. Я добавил «несовершенный».
Старынкевич
Я прочитал ваши ссылки, они были интересны, но было бы полезно, если бы вы могли добавить указатель на раздел для каждого Q / A каждый. После прочтения tty demysified я начал stty -a > /tmp/test1в bash, а затем команду, которую я отменил. Цвет терминала теперь красный. stty -a > /tmp/test2но test1и test2были точно такими же.
Джонас Стейн
1

Реакция на эту проблему не является полностью независимой от оболочки. В zsh есть ttyctlвстроенная функция, которая может «заморозить» или «разморозить» режим tty. Я не думаю, что есть эквивалент в Bash. Команда settyв tcsh делает то же самое, но более детально: вы можете заморозить отдельные настройки.

Замораживание режима tty просто означает, что zsh запомнит текущий режим, и если какой-то будущий потомок изменит его, режим будет восстановлен, когда потомок приостановит или завершит работу.

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

resetделает больше, чем sttyрежимы восстановления , так что иногда вам это может понадобиться, но не часто.


источник
Действительно: я запустил stty -a> / tmp / test1 в bash, а затем команду, которую я отменил. Цвет терминала теперь красный. stty -a> / tmp / test2, но test1 и test2 были абсолютно одинаковыми. Я попытался сделать то же самое с tcsh, но я не смог завершить свою команду с помощью CTRL + C. Цвета остались в порядке.
Джонас Стейн