I'm using FreeBSD 11 with PuTTY for SSH. The keyboard's key codes don't seem to be set up at all correctly - for example it beeps on up arrow and inserts '~' for most navigation keys including basics like arrows and delete key. The keyboard is a standard UK English keyboard. Typing is a real pain.

I've read a number of threads about setting key codes, both in rc and shell, so I know I can set it up that way as a last resort.

But it would be very odd for a client with so much configurability, and an OS with such wide use, not to have some terminal option / setting in common that they both "just understand", that I can set on both and voila - the keys all (or mostly) work. The trouble is I have no idea how to find it and, when I do find it, how to set it for all future sessions.

I understand how to find the keycode being sent by the terminal for an individual key, so I could set up my keys that way, one by one. But I would like to find basic terminal settings for my shell rc and for PuTTY, that gets as many keys as possible understood by both, so I only have to set up a few exceptions if I need them.

How can I do this?

  • It "should" work with the default settings for putty (although there are many differences between putty and xterm, the FreeBSD termcap for "xterm" would work if you do not expect anything from modified keys). – Thomas Dickey Oct 9 '17 at 13:44

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

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.


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):


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.

| improve this answer | |
  • The ultra short answer just needs to have "And set the TERM environment variable to putty too." (-: – JdeBP Oct 9 '17 at 14:55
  • It is FreeBSD bug #175394, by the way. Filed in 2013 and still marked "in progress". – JdeBP Oct 9 '17 at 14:57
  • When you set putty in Putty config the TERM environment is set automatically. You need nothing else (if standard FreeBSD!) – Claus Andersen Oct 9 '17 at 15:00
  • I linked to 175394 on the mailinglist as I (still) cannot find it in Bugzilla bugs.freebsd.org - so I doubt anyone will pick it up – Claus Andersen Oct 9 '17 at 15:04
  • You're not thinking like a user. Users do things like explicitly set TERM in their ` ~/.profile` and then wonder why things do not work. We even have questions about it and answers telling people to do it. See unix.stackexchange.com/questions/198794 , unix.stackexchange.com/questions/91977 , and unix.stackexchange.com/a/121134/5132 for (just some) examples. – JdeBP Oct 9 '17 at 15:06

I can't comment, but the answer by @clausandersen is very thorough. However, the bonus section about adding a termcap entry isn't quite correct. Calling tput AF 100 won't work as expected, because the termcap AF capability inherited from the putty entry only supports 8 colors. This should work as intended:

putty-256color|PuTTy - 256 colors:\
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.