Getting PuTTY to work properly with FreeBSD

There are so many knobs to twist and turn. And much advice on the Internet people follow blindly. As always many ways to Rome but when you know how things are connected they are very simple.

The ultra short answer is:

Change the terminal string in Putty from xterm to putty (under Connection -> Data -> Terminal-type string).

The typical pitfall to avoid:

Make sure that you are not setting TERM elsewhere in your rc files.

The slightly longer answer:

First I would start by ensuring that you are actually using the defaults. From my personal Windows 10 laptop using DK keyboard (and mapping) I connect to a FreeBSD 11.1 setup with DK mapping. In my case the arrow keys works as expected on the command-line. Left/right moves on current line. Up/Down goes through command history.

I have verified this for both /bin/sh (default user shell) and /bin/tcsh (default root shell). You can read up on shells.

You write that you know how you can do your keymapping in the shell rc file. Many suggestions on how to do this is floating around. But it is usually not what you should do.

You will find suggestions like this for tcsh keybindings:

# Del(ete), Home and End 
bindkey "\e[3~"   delete-char
bindkey "\e[1~"   beginning-of-line
bindkey "\e[4~"   end-of-line

And suggestions like this for bash ( ~/.inputrc)

"\x7F": backward-delete-char
"\e[3~": delete-char
"\e[1~": beginning-of-line
"\e[4~": end-of-line

But rather than setting these bindings locally for each session and each shell you should rather use termcap/terminfo for this purpose (more on this later).

In this context Putty is your terminal.

The default for Putty is to set TERM for your session to "xterm". It does that because it is reasonably xterm compatible. xterm is not a reference to any terminal but for the program Xterm.

PuTTY Configuration

Connection -> Data -> Terminal-type string: `xterm`

When you have logged in you can verify this setting carries through to your session:

echo $TERM
xterm

If $TERM does not match what you have set in Putty then you might have set an override in your rc files. Notice the warning for /bin/sh in ~/.profile:

# Setting TERM is normally done through /etc/ttys.  Do only override
# if you're sure that you'll never log in via telnet or xterm or a
# serial line.
# TERM=xterm;   export TERM

Because we do not use a lot of physical DEC VT100's anymore xterm is what you will see many places.

Even if you just keep TERM as xterm you will get colour output with default Putty and FreeBSD as ls -G will work.

Some will recommend that you set TERM to xterm-color, xterm-256 or rxvt-256color to get "proper" colour support.

But remember: All these magic TERM values are just mappings in a database. A reason xterm is so prevalent today is that some programs and script checks if $TERM begins with xterm (which is a horrible idea).

This then brings us back to termcap which is the default on FreeBSD. If you want to use terminfo then you will need to install devel/ncurses. For more on this see: How can I use terminfo entries on FreeBSD?

You can find the source of the termcap database in the text file /usr/share/misc/termcap. If you make changes to this file you need to run cap_mkdb to get the system to acknowledge the change. In here you will find the answer to your conundrum. There is an explicit TERM setting for Putty named: putty.

FreeBSD has then made the choice not to change the settings for xterm to match Putty's behavior (probably due to combatibility concerns). But they have been nice enough to supply a setting for Putty.

So if you change the Putty default setting for Terminal-type string: from xterm to putty then this is is reflected in TERM when you log in. And the default FreeBSD termcap has an entry for this.

And by magic and without touching a lot of rc files you now have working arrow keys (I had that with xterm as well) but also Home/End moves to start/end of line and Del(ete) deletes.

Bonus:

It seems the default putty definition does not support all 256 colours. You can then modify your termcap and add these two lines (and run cap_mkdb):

putty-256color:\
        :pa#32767:Co#256:tc=putty:

Then you can set your TERM to putty-256color. Scott Robison suggested this should be added - but the change has not been picked up by FreeBSD. I cannot find this PR in the database anymore.

Bonus 2:

If you prefer to keep TERM as xterm then you should spend time configuring Putty to match what FreeBSD expects of the xterm terminal.

If you go to the settings Terminal -> Keyboard in the setting The Home and End keys you can change "Standard" to "rxvt".

With this change you will notice the Home key works on the command line (moves to start of line). But End now does nothing.

So it is then a question of getting Putty to agree with what FreeBSD expects from an xterm. Just to show that you can also go the other way around.