Я понял секрет!
Как я уже писал в "редактировании" выше, удаленной оболочкой был BusyBox ash , а не bash .
Из libbb/lineedit.c:2336-2338 , в источниках BusyBox:
/* Print out the command prompt, optionally ask where cursor is */
parse_and_put_prompt(prompt);
ask_terminal();
Это используется для распечатки командной строки в ash . Но обратите внимание, как только он выводит подсказку, вызывается другая функция с именем ask_terminal . Что делает ask_terminal ? Он печатает следующие символы: <ESCAPE>[6n .
Вы никогда не увидите этих персонажей в своем терминале. На самом деле они представляют собой управляющий код управления терминалом ANSI. <ESC>[6n - это команда "Query Cursor Position" - она говорит эмулятору терминала отправить обратно другой управляющий код ANSI, который сообщает оболочке, где находится курсор (точка вставки текста) в окне терминала.
Поэтому, как только вы нажмете Enter , ash напечатает <ESC>[6n , и sshd передает это обратно в ssh а оттуда в эмулятор терминала. Сразу же, прежде чем вы сможете нажать ~ , ваш эмулятор терминала отправляет что-то вроде <ESC>[47;13R на стандартный ввод, и ssh передает это по соединению к sshd и оттуда к ash , сообщая ash где находится ваш курсор.
Теперь клиент SSH на самом деле не знает, что означают эти escape-коды ANSI. Для SSH это все символы, считываемые из стандартного ввода. Вместо того, чтобы видеть <ENTER>~C , SSH-клиент видит <ENTER><ESC>[47;13R~C , и поскольку он не видит ~ сразу после Enter , он не думает, что это escape-код ,
Вопрос в том, что с этим делать. Было бы хорошо, если бы OpenSSH понимал эти экранированные значения ANSI, отправленные терминалом, и все равно принял бы символ выхода ~ после команды управления терминалом ANSI. Я могу прислать ребятам из OpenSSH патч и посмотреть, хотят ли они исправить это ...