Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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]$
share|improve this question
1  
Have you tried ssty erase '^?'? If the devices insist on a C-h, it's not telnet's call, it's the terminal (emulator)'s. –  Gilles May 18 '11 at 20:49
    
@Gilles your comment is actually not correct, see my answer below –  Mike Pennington May 19 '11 at 13:22
add comment

3 Answers

up vote 2 down vote accepted

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.

share|improve this answer
2  
stty erase $ doesn't map the "backspace" key to "$", it tells the tty driver that in order to erase a character, the "$" key need to be used. When you run telnet, you are in raw mode so this setting is ignored. A simple solution would be to configure your terminal emulator to send ^H for backspace, as god intended, another one is using your hack which translates these character on the fly using expect. –  jlliagre May 19 '11 at 13:41
    
@jlliagre, yes, I discovered how stty did not change telnet's keyboard reads when I used wireshark; however, this important fact was not clear to me until I sniffed. I will investigate how I can change Backspace to use Control_h in rxvt... or maybe I need to think about finding another term. –  Mike Pennington May 19 '11 at 13:44
    
@Mike: I think you're still confused about something (which I admit neither jlliagre nor I mentioned explicitly; I've updated my answer). stty needs to run on the application side. I highly doubt telnet is translating input characters or that you need to use script; just running stty on the remote machine will probably do the trick. –  Gilles May 19 '11 at 14:40
    
@Gilles, the remote machine is a network device, it does not have stty. –  Mike Pennington May 19 '11 at 14:47
1  
@Mike: When you use netcat, your terminal is in cooked mode: you write a line, editing it locally, and Enter sends it. When you use telnet, your terminal is in raw mode: each character is sent immediately to the application. See e.g. the beginning of this page, or this Wikipedia article. –  Gilles May 19 '11 at 15:01
show 2 more comments

Backspace and Control-H were designed to be the same thing but nowadays, especially on Linux, you often have backspace sending delete and delete sending some odd escape sequence.

In any case and as far as I know, telnet or the TERM variable shouldn't change what backspace sends, this is usually a terminal emulator configuration feature.

share|improve this answer
    
Your question is based on the assumption telnet is doing specific processing of the backspace key which I believe is wrong. I should have put that as a comment instead of an answer indeed. –  jlliagre May 19 '11 at 13:23
    
AFAICT, telnet pays no attention to local terminal mappings of the keyboard. Anne Barreta's notes about the keyboard and telnet –  Mike Pennington May 19 '11 at 13:27
    
I'm afraid you are misunderstanding what stty does. –  jlliagre May 19 '11 at 13:35
add comment

Programs are supposed to query the terminal settings to find out what the backspace character is (^h and ^?, i.e. \010 and \177, are the two choices out there). Use stty erase '^h' or stty erase '^?' to declare what your terminal sends.

If you log in remotely (with telnet, rsh or ssh) inside the terminal, note that you must run stty on the application side. stty doesn't tell the terminal to do anything different, it informs the local terminal driver (i.e. the part that interfaces with applications running in the terminal) about the terminal (historically a physical object, now a terminal emulator) settings. Similarly, if you run Screen or similar terminal-in-terminal software, you need to run stty in each screen window (but usually Screen can be configured to do the right thing from its configuration file, if it doesn't work out of the box).

The difference in behavior that you observe from netcat vs. telnet is due to the way the terminal is used: * In netcat, the terminal is in line-by-line mode (also called “cooked mode”). You edit a line (using the local terminal's built-in edition feature, and so in particular the local stty settings), then send it in its final state to the remote host. * In telnet, the (local) terminal is in character-by-character mode (also called “raw mode”). Every keystroke goes directly to telnet which relays it immediately to the remote system. You are dependent on the remote system's line edition features.

There are broken programs out there that don't care about the terminal settings. Looks like you've encountered one of them. Your best bet is to change your terminal's configuration. The same goes if you need to communicate with a device over a remote protocol such as telnet or SSH and the device is not configurable.

With xterm, it's easy: there's a setting to toggle the character sent by the BackSpace key at run-time. From the left button menu, toggle “Delete is DEL”. Programmatically, send the escape sequence \e[?67h to have BackSpace send ^h, or \e[?67l to have BackSpace send ^?. The corresponding resource is XTerm.backarrowKeyIsErase. Other terminal emulators may or may not have a similar interface feature or support the escape sequence.

Many terminal emulators send one of ^h or ^? when you press BackSpace, and the other character when you press Ctrl+BackSpace. This can be useful in a pinch.

Note that showkeys and friends are only relevant on the Linux console, not within X.

share|improve this answer
    
sadly even this has not fixed the problem, but I finally found a solution (or perhaps I should say kludge)... see my answer below. –  Mike Pennington May 19 '11 at 13:07
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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