Red Green Repeat Adventures of a Spec Driven Junkie

TIL: SSH Disconnect Sequence and Escape Characters

If you use SSH over an unstable connection, this article will be a great tip on how to quit SSH while keeping the host terminal open and to also find more details about other features in SSH.

Motivation

I use SSH to connect with remote servers. Over a bad connection where the connection can drop. When the connection drops, the SSH client becomes unresponsive for a little while because it is unsure of the connection state and will try to keep reconnecting. During this period, SSH will receive keys, but will not respond.

If I want to disconnect during this state, it is impossible as any input is being queued. To disconnect from an unresponsive SSH connection, shutting down the whole terminal program is how I usually accomplish this, which normally is not hard, but on an iPad terminal, it gets annoying pretty fast.

Command

The quick way to disconnect SSH is to enter this key combination:

<Return> ~.

Sequentially press the Return, tilde, and period keys.

How I found it

Originally, a coworker told me about this nifty trick and I found it a great way to disconnect hanging SSH sessions.

Learning more

When I read this answer, by my favorite Python programmer Aaron Hall, I found there are more escape characters for SSH. These are described in detail in the SSH man page:

$ man ssh
...
ESCAPE CHARACTERS
When a pseudo-terminal has been requested, ssh supports a number of functions through the use of an escape charac-
ter.

A single tilde character can be sent as ~~ or by following the tilde by a character other than those described
below. The escape character must always follow a newline to be interpreted as special. The escape character can be
changed in configuration files using the EscapeChar configuration directive or on the command line by the -e option.

The supported escapes (assuming the default `~') are:

~. Disconnect.

~^Z Background ssh.

~# List forwarded connections.

~& Background ssh at logout when waiting for forwarded connection / X11 sessions to terminate.

~? Display a list of escape characters.

~B Send a BREAK to the remote system (only useful if the peer supports it).

~C Open command line. Currently this allows the addition of port forwardings using the -L, -R and -D options
(see above). It also allows the cancellation of existing port-forwardings with -KL[bind_address:]port for
local, -KR[bind_address:]port for remote and -KD[bind_address:]port for dynamic port-forwardings. !command
allows the user to execute a local command if the PermitLocalCommand option is enabled in ssh_config(5).
Basic help is available, using the -h option.

~R Request rekeying of the connection (only useful if the peer supports it).

~V Decrease the verbosity (LogLevel) when errors are being written to stderr.

~v Increase the verbosity (LogLevel) when errors are being written to stderr.
...

There’s a lot more great information on the SSH man page, like configuration files, or how to setup a VPN over SSH. It’s quite impressive the amount of documentation SSH has.

Conclusion

I learned how to gracefully disconnect a hanging SSH session with simple key commands: <Return> ~ . and also learned more features of SSH through its UNIX man page.