I've figured out the secret!
As I posted in the "edit" above, the remote shell was BusyBox ash
, not bash
.
From libbb/lineedit.c:2336-2338
, in the BusyBox sources:
/* Print out the command prompt, optionally ask where cursor is */
parse_and_put_prompt(prompt);
ask_terminal();
That is used to print out the command prompt in ash
. But notice, as soon as it prints the prompt, another function called ask_terminal
is called. What does ask_terminal
do? It prints out the following characters: <ESCAPE>[6n
.
You never see those characters in your terminal. Actually, they are an ANSI terminal control escape code. <ESC>[6n
is a "Query Cursor Position" command -- it tells the terminal emulator to send back another ANSI escape code, which tells the shell where the cursor (text insertion point) is located in the terminal window.
So as soon as you press Enter
, ash
prints out <ESC>[6n
, and sshd
passes that back to ssh
and from there to the terminal emulator. Immediately, before you can press ~
, your terminal emulator sends something like <ESC>[47;13R
to standard input, and ssh
passes that over the connection to sshd
and from there to ash
, telling ash
where your cursor is.
Now, the SSH client doesn't actually know what those ANSI escape codes mean. To SSH, they are all just characters read from standard input. Rather than seeing <ENTER>~C
, the SSH client sees <ENTER><ESC>[47;13R~C
, and since it doesn't see the ~
right after Enter
, it doesn't think that it is an escape code.
The question is what to do about this. It would be nice if OpenSSH understood those ANSI escapes sent by the terminal and would still accept the ~
escape character after an ANSI terminal control command. I may send the OpenSSH guys a patch and see if they are interested in fixing this...
1
~.
and~C
work for me in Bash too (when using SSH on a Mac). – Arjan – 2015-10-12T08:28:05.777In case it makes a difference,
ssh -V
printsOpenSSH_6.6.1p1 Ubuntu-2ubuntu2.3, OpenSSL 1.0.1f 6 Jan 2014
. – Alex D – 2015-10-12T08:33:44.930On my up-to-date Mac it's much older, OpenSSH_6.2p2, OSSLShim 0.9.8r 8 Dec 2011... – Arjan – 2015-10-12T08:55:24.753
Just in case it might be related to the remote SSH server: I get the same (expected) behaviour when using
ssh localhost
. The remote host I tested with earlier shows OpenSSH_4.3p2, OpenSSL 0.9.8e-fips-rhel5 01 Jul 2008. Wow... ;-) – Arjan – 2015-10-12T09:06:18.320