一个困扰了我很久得问题:xterm中<backspace>或<delete>键无法删除敲错的字符,只能使用Ctrl+H或者VI删除模式,很不方便。操作系统是Red Hat Enterprise Linux 5.5。
Google之后发现这个问题比较普遍,但是很多建议都不能解决问题。最终在http://forums11.itrc.hp.com/service/forums/questionanswer.do?admit=109447626+1298028466012+28353475&threadId=1158640发现了一个可行的办法:
stty erase <backspace>
当然在设置之前要先用stty -a查看erase=XX是不是已经设置成了<backspace>,即^?。
如果不想每次打开一个新的xterm之后都要手动输入stty erase <backspace>,可以在.env中加入
stty erase ^?
PS:发现了一个详细解释并彻底解决各种Unix/Linux窗口中<backspace>或<delete>不一致的文章:http://www.ibb.net/~anne/keyboard.html。转载如下。
The Linux Hall of Shame
http://www.ibb.net/~anne/keyboard.htmlversion 0.6 Last updated 11/18/2008 13:08:02
Main Page| The Alternative Way | Troubleshooting
The keymapping problem can be traced back to the time when computers used punched tapes. The only way to correct a wrongly punched character was to punch additional bits in the tape (or rather, punch additional bits _out_ of the tape). Characters with all the bits punched were treated as deleted characters. See 'man ascii' for a list of the ASCII characterset, you'll see that DEL, (octal 177, decimal 127 and hexadecimal 7F) is the one with all the bits punched in (the ASCII code with the highest value). To be able to overwrite a character it is necessary to undo the feed between the characters first. For this the ASCII BS (octal 010, decimal 8, hexadecimal 08) was used. So to erase the last-typed character, you would have to press first BS to move back one character, and then DEL to delete the character. In newer computers either BS or DEL was chosen to move back and delete in one press.
The question to use BS or DEL was (and is...) just a matter of choice, just as different operating systems chose different ways to represent newlines, which was done by first issuing a carriage return (CR) and then a line-feed (LF). UNIX chose ASCII LF (hexadecimal 0A) to do both at the same time, Macintosh chose CR and MS-DOS both. Unfortunately, in the BS-DEL case, Linux ended up with two possibilities.
The essential point in this issue is to go for one way consistently. This page describes a way to consistently use DEL to erase the previous character, the page called The Alternative Way describes a way to consistently use BS. On the latter page there are some tips which may be useful regardless of what approach you take.
Since starting this page in 1997, most distributions have sorted out the issue. Still, some of the fixes/workarounds can be useful when working in a mixed environment, or when working on older systems. And evidently, given the number of hits the page still gets, it's a situation common to more then a few people ;-)
If you miss an application on this page, it's either because the keys are ok in the application ("If it ain't broken, don't fix it"), or because I don't know about it. In either case, don't hesitate to mail me about it.
The linux console emulates a vt220 terminal which has the following key-mapping:
Linux console/VT220 Key KeySymName Console characters -------------------------------------------------- Ctrl+H ---> Control_H ---> ASCII BS (0x08) [<---] ---> Backspace ---> ASCII DEL (0x7f) [Delete] ---> Delete ---> "/e[3~" Note 1: BS (0x08) is equivalent to ^H, which is left to be used by applications (e.g. for help menus in emacs, but it could be anything). DEL is equivalent to ^?, or 0177 (octal) and 0x7f (hex) and "/e[3~" will show up in your xterm (using the ^v-trick) as ^[[3~. Xterms on the other hand, emulate the vt100 terminal, which didn't have a [Delete]. It did have a [<---] which generated ASCII BS (but it was in an awkward position and did not serve as rubout). VT100 -- Key KeySymName Console characters -------------------------------------------------- Ctrl+H ---> Control_H ---> ASCII BS (0x08) [<---] ---> Backspace ---> ASCII DEL (0x7F) Now here's how xterm emulates the VT100 terminal: Xterm's emulation of VT100 Key KeySymName Console characters -------------------------------------------------- Ctrl+H ---> Control_H ---> ASCII BS (0x08) [<---] ---> Backspace ---> ASCII BS (0x08) [Delete] ---> Delete ---> ASCII DEL (0x7F) It may be clear that by default the keys are mapped differently on the console and in xterm. This would be ok if it weren't for the fact that while on the console ^H is free to be used by applications, in an xterm it is not (instead it's mapped to the [<---] key). Differences between terminal types are generally dealt with by the terminfo database (see below), mapping terminal specific strings to the correct key. However, in this case, the ^H should not be mapped. Terminfo is not enough, the settings of the terminal (xterm) have to be modified such that ^H is not used.In my previous attempt at working around the problem, I put most of my effort in trying to map all keys to suit xterm's vt100 emulation. However, I now propose another way to deal with the problem. This basically means getting xterm to work with the consoles' default settings: [<---] will do ASCII DEL (0x7F, or ^?), and [Delete] will do "/e[3~". This way ^H is not used for any terminal specific functions, it can be used by applications.
When you change the keymapping on your own system, you may have problems when accessing other systems. Luckily, this can be worked-around by a script which changes the input it receives to the output that is expected by the application (telnet, rlogin). See the telnet section.
Rxvt only uses Xresources if it is compiled with this option. Since rxvt uses readline, to get home and end to work you will have to edit .inputrc, see the Bash section). Redhat users can pick up the SRPM (source) and compile rxvt themselves with this feature.h, ensuring the right keybindings.
Putting xterm or nxterm in front of *vt100.translations makes the settings specific for xterm or nxterm. Sometimes this does not seem to work properly, in that case try using bothnxterm*VT100.Translations and xterm*VT100.Translations.
BTW, have I told you that Ctrl-v <key> will tell you what sequence is sent to the shell? Try Ctrl-v [Delete], it should give a ^[[3~ in your xterm or console (try it with [ESC] and you'll find ^[, which corresponds to /e for readline apps, and /033 for Xresources).
1. The syntax of the Xresources files is very strict, make sure you don't leave blank spaces after the backslash on each line. Also watch the newline (/n/) sequences, there shouldn't be one at the last line of an entry.2. The sections are named, if you only use *VT100.Translations it will work for all xterm and friends.3. For info about Xresources and other X related stuff refer to 'man X'.
keycode 22 = BackSpacekeycode 107 = Delete
Note that the keycodes in X are not the same as in a VT. Use showkey to see the keycodes generated by the keyboard in a VT, and xev in X. There is an excellent graphical front end for X-keyboard configuration: xkeycaps. Refer to the Netscape section.
Another way of generating special characters in X (without using xmodmap) is by defining a Compose-key (for use as a "dead key") in XF86Config in the Keyboard section:
RightCtl Compose Now you have a compose-key with the same properties as the one described in the VT section. Remember to set the environment variable LC_CTYPE=iso-8859-1 (see VT optional...). Consult 'man XF86Config' if you want to know more. Note: this doesn't seem work rxvt. Alternatively, owners of a windows keyboard (one with extra buttons, it need not be a M$ natural keyboard) can enable the XKEYBOARD extension (enabled per default) in XF86Config and uncomment the line (follow the instructions in the file): XkbModel "microsoft" Now you can use the button with the windows flag on it to produce a great number of exotic characters, just press it in combination with e.g. a, producing á (a clear disadvantage is that there is no logic in the location of the special characters at all...).Yet another way to use "dead keys" in X is by installing a modified version of libX11 which includes support for dead keys (transparent for all apps). First, get the modified version of libX11 (make sure you get the right version, if you use glibc replace both libX11, ELF-libc5 and ELF-libc6). Now, deactivate the XKB extension of XFree86 (edit XF86Config and run xmodmap on a Xmodmap file with dead keys like dead_acute, dead_grave, dead_cedilla, dead_ogonek and a Multi_keys one too.
A special case is if you use xdm, you need to deactivate XKB from the /etc/X11/xdm/Xservers file, passing a -kb parameter to the server like this:
:0 local /usr/X11R6/bin/X -kb then in /etc/X11/xdm/Xsetup_0 file add a line to load the Xmodmap, like this: if [ -r /etc/X11/xinit/.Xmodmap ]; then /usr/X11R6/bin/xmodmap /etc/X11/xinit/.Xmodmap fi Now chars accesible by AltGr, dead keys or compose are usable in xdm too.Create a file, /etc/inputrc for system wide use or ~/.inputrc for personal use. Actually, this is the readline initialization file, readline is a library that some programs (bash, kvt) use to read input (try bind -v to see a list of readline key and function bindings). Cut and paste the following in the file to make the Delete key delete characters under the cursor, and make Home and End work as well:
"/e[3~": delete-char # this is actually equivalent to "/C-?": delete-char # VT "/e[1~": beginning-of-line "/e[4~": end-of-line # kvt "/e[H":beginning-of-line "/e[F":end-of-line # rxvt and konsole (i.e. the KDE-app...) "/e[7~":beginning-of-line "/e[8~":end-of-line If a system-wide /etc/inputrc was created, add the following line to /etc/profile: export INPUTRC=/etc/inputrcMake sure that the stty erase character is set to ^?. Type
stty -a | grep eraseand check if it says
erase = ^?;If it is set to something else (e.g. ^H) then put the following line in both .bashrc and in either .bash_profile or /etc/profile:
if tty --quiet ; then stty erase '^?' fi and for xterm and rxvt add this to .Xdefaults: *ttyModes: erase ^?If you create /etc/inputrc, note that Bash will ignore ~/.inputrc (currently this happens in all distributions except Debian, however, this might change in the future). As an alternative, you can edit~/.inputrc, and copy this to /etc/skel/, so it's in the home directories of all new users.Push the key-combination 'Ctrl-x-r' (push the control-key, the x-key. release it, push the r-key, release it, and then release the control-key) to see if the changes in inputrc take effect. Or just login again, and it will work.
You can also change the keybindings on the fly with the bind command, e.g:
[localhost]> bind "/C-?": backward-delete-char This is useful to test different keybindings, if they work you can put them in ~/.inputrc. Read all about it in the readline manpage.People using keymaps with e.g. Scandinavian characters who would like bash to display these characters (øl;-) have to add the following lines in .inputrc:set convert-meta offset output-meta onset input-meta onFor more info, check the Danish-HOWTO.
[localhost]> source .cshrc
Add the following line to /etc/profile:
export LESS="-MM -k/etc/less"Now type:
[localhost]> . /etc/profile
By fiddling with these settings you should be able to get less to accept (all of) the holy keycodes, at least, it works on my computer. For some exciting reading, check 'man lesskey'.
Save the file, and the next time you start nedit the Delete key will do what we want it to: delete under the cursor. Note: you can also put the line in ~/.nedit, but every time you save the default settings, the.nedit file will be overwritten, and you'll have to (n)edit it again.
Note the nedit, as e.g. netscape, is a motif application. This means that it uses the XKeysymDB, see thet netscape section.
If you use xmodmap, you may want to check out the graphical front end for X-keyboard configuration: xkeycaps. Get the .rpm at RedHat Powertools, or get the Debian-package (or plain tarball). It's a nice tool. You can also look for a default Xmodmap file on your system. At any rate, make sure that the following is in the file:
keycode 22 = BackSpacekeycode 107 = Delete
alternatively, you can put it in e.g. your .Xclients file, or in /etc/X11/xdm/Xsetup_0):
# map the [<---] key to the [BackSpace] keysym. xmodmap -e "keycode 22 = BackSpace" # map the [Delete] key to the [Delete] keysym. xmodmap -e "keycode 107 = Delete"# Specifies the program invoked by ^_ in the Composer,# or the "enable-alternate-editor-implicitly" feature.editor=
You can enter the command for any editor here, e.g. joe or vi.
If you want the editor to be started right away, start pine, enter SETUP and Config and select the enable-alternate-editor-implicitly option. Now the editor of choice will be started automagically when you start writing a message.
Pico fans may want to try jpico, which is basically joe with pico keybindings (and all the extra's joe offers). Others my be even smarter and switch to vim and mutt. Note that the first can be taught to do theCtrl-j-trick, the latter can use pine keybindings.
The logical next step is to automate the trick. Create a file, /etc/broken-backspace-hosts (or a shorter name...). In this file, list the hosts which expect ^H and ^? instead of ^? and ^[[3~. Now you can make a wrapper for telnet as shown below. This particular script assumes that the telnet binary has been renamed telnet.orig, and that the kbdfix script described in the previous section is somewhere in your path):
#!/bin/sh if [ "$#" -ge 1 ]; then if grep -wq "$@" /etc/broken-backspace-hosts ; then exec kbdfix telnet.orig "$@" else exec telnet.orig "$@" fi else exec telnet.orig fi From now on, when you use telnet, the script will check whether the host you are telnetting to is considered broken (listed in the /etc/broken-backspace-hosts file). If it is, the expect script (kbdfix) will be used, if not, telnet will be started directly. Without arguments the original telnet executable will run (thanks to Jason Bonser for this addition). You can do the same for rlogin, although rlogin can't be moved (i.e. won't work when it isn't called rlogin).This document was put together by Anne Baretta (anne (at) ibb.net). Please mail me if you find mistakes, tY-pO's, alternative or plain better solutions. A few people have already pointed out many mistakes (there simply cannot be that many left...), which improved the document a lot. I would like to thank all the people who contributed to the page, and Thomas Telkamp for hosting the site.
This page is maintained by Anne Baretta. Last updated 11/18/2008 13:08:02
