Странность символа Backspace

Интересно, почему символ возврата в обычные терминалы Linux на самом деле не стирает символы при печати (что обычно работает при вводе).

Это работает так, как ожидалось:

$ echo -e "abc\b\b\bxyz"
xyz

(\b оценивается как backspace, может быть также вставлен как Ctrl+V Ctrl+H — отображается как ^H ( 0x08))

но когда после backspaces меньше символов, обнаруживается странное поведение:

$ echo -e "abc\b\b\bx"
xbc

он ведет себя как клавиши со стрелками влево вместо возврата:

$ echo -e "abc\e[D\e[D\e[Dx"
xbc

стереть строку назад работает нормально:

$ echo -e "abc\e[1Kx"
x

На самом деле, когда я набираю Ctrl+V Backspace в терминале, вместо ^H выдается ^? (0x7f), это Del символ ascii, но Ctrl+V Del дает <ESC>[3~, но это уже другая история..

Так может ли кто-нибудь объяснить, почему напечатанный символ возврата не стирает символы?

(Моя среда - xterm Linux и некоторые другие эмуляторы терминала, $TERM == xterm, также пробовал vt100, Linux)


person mykhal    schedule 18.05.2010    source источник


Ответы (1)


То, что вы видите, верно. Backspace или ^H перемещает курсор влево, без стирания. Чтобы стереть символ, нужно вывести ^H ^H (Backspace-Space-Backspace).


Чтобы ответить на ваш комментарий, Backspace определен таким образом в семействе терминалов VT100 / ANSI, из которого заимствовано множество последовательностей кода управления терминалом. См. руководство пользователя VT100 здесь, в котором функция BS определяется как "Перемещает курсор влево". одна позиция символа, если только он не находится на левом поле, и в этом случае никаких действий не происходит». Другими словами, это причуда истории :)

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

person clstrfsck    schedule 18.05.2010
comment
ну, это не объяснение, почему управляющий символ backspace ведет себя как левая клавиша курсора, а не в соответствии со здравым смыслом (удалить последний символ) - person mykhal; 18.05.2010
comment
НАСТОЯЩАЯ причина, по которой это работает, заключается в том, что еще более старые терминалы с бумажными копиями печатают на бумаге, как пишущая машинка. На таком терминале НЕТ возможности стереть символ после его вывода. Терминалы, похожие на пишущие машинки, также являются причиной того, что мы до сих пор застряли с отдельными символами возврата каретки и перевода строки в конце строк в Windows. - person alexis; 12.03.2012
comment
Кстати, не знаю насчет здравого смысла, но backspace означает перемещение назад, а не стирание. В любом случае мне все равно, но Ричард Столлман довольно красноречиво говорил о том, насколько ошибочен ваш подход и что Delete — это настоящее стирание. Он отказался освобождать ключ ^H в emacs, так как не был заинтересован в обслуживании сломанных протоколов или чего-то в этом роде. :-) - person alexis; 12.03.2012
comment
Также F^HF выделен жирным шрифтом, этот вывод создается man и less обрабатывает его, попробуйте echo -e F^HFO^HOO^HO | less. Теперь я понимаю, почему это просто напечатать один и тот же символ дважды в одном и том же месте. - person jcubic; 23.09.2012
comment
Код @jcubic у меня не совсем работал. Для тех, кто хочет поиграть с этим, попробуйте echo -e 'F\bFO\bOO\bO' | less - person jpyams; 21.09.2017
comment
@jpyams Я не помню, но я думаю, что ^H - это просто представление \b, а не буквально два символа. Я думаю, что показываю это так, потому что так это было представлено в ответе. - person jcubic; 21.09.2017
comment
@jcubic это имеет смысл. Я разместил команду, которая сработала для меня, только для тех, кто захочет поиграть с тем, о чем вы говорите в будущем. - person jpyams; 24.09.2017