Linux – Force telnet / ssh to use crtl-H for backspace

linuxrxvttelnetterminalterminal-emulator

I have some devices connected to a Cisco serial term server; many work fine when I telnet directly to the port on the Cisco. However, I have a few stubborn devices that will not use Backspace as it is mapped in telnet by default.

In case it matters, I telnet from rxvt under Debian squeeze (in an X Window). TERM is set to rxvt, but it doesn't matter whether I use vt100, vt101, or xterm… changing TERM has no effect. I started down the road of changing TERM based on what I saw in an old Kermit FAQ. FWIW, stty erase ^h and stty erase ^? don't work either.

I have noticed that Backspace works correctly on these devices if I use a raw TCP socket from netcat… i.e. nc 192.168.12.117 2006; however, then I run into other issues with passwords not hidden or terminal paging.

How can I selectively force telnet and ssh to map Backspace to CtrlH for these devices? Also, what criteria should I use to evaluate whether this is a bug in the device?

EDIT

In case it matters, this is the output from showkey -a for the keys in question… ^? corresponds to Backspace and ^H is CtrlH. It seems like I should be getting close when I look at The Linux Keyboard and Console Howto, but I can't seem to decipher what I can do to change this. I have tried various incantations with loadkeys to no effect.

[mpenning@hotcoffee docs]$ sudo showkey -a

Press any keys - Ctrl-D will terminate this program

^?      127 0177 0x7f
^H        8 0010 0x08

I am also including relevant output from dumpkeys as well… this is the current mapping in my system (which doesn't work on some devices in question). If I could figure out how to get Backspace to do the same thing as CtrlH, I would have a solution.

[mpenning@hotcoffee docs]$ sudo dumpkeys | grep -Ei "backspace|127"
keycode   8 = BackSpace        ampersand        braceleft       
keycode  14 = BackSpace        Delete          
        control keycode  14 = BackSpace       
keycode 127 =
[mpenning@hotcoffee docs]$

Best Answer

I finally found an answer in Anne Baretta's Linux Keyboard Hall of Shame... it seems that changing key mappings in xterm / rxvt does no good for telnet.

I validated this when I sniffed the telnet connection. First I sniffed the telnet session and saw that Backspace sent 0x7f to the host. Next I intentionally broke Backspace in rxvt using stty erase $ (thus mapping my Backspace to the dollar sign in rxvt). After doing this, I had to hit $ to backspace in rxvt, but telnet still sent 0x7f when I used Backspace on the remote host.

SOLUTION

Create a script called kbdfix (below), and make it executable with 755 permissions; you will need the tclsh and expect packages loaded from your distribution archives.

#!/usr/bin/expect

#Name this file as kbdfix and make it executable in your path
eval spawn -noecho $argv

interact {
 \177        {send "\010"}
 "\033\[3~"  {send "\177"}
}

Now to connect to the broken hosts, I type kbdfix telnet 192.168.12.117 2006, and Backspace works.

Note for anyone confused by 2006 above... that is the TCP port that the Cisco term server uses for the serial connection to the console of the broken device (in this case, a Brocade FCX switch).

If you are merely telnetting to a device that doesn't like Backspace, you would use kbdfix telnet <addr_of_the_broken_device>. I am also using this with ssh when I ssh to a DLink DGS-3200 Ethernet switch that has similar issues; the syntax is kbdfix ssh 172.16.1.26.

Related Question