再次注意,困扰人们尝试修复其系统的主要问题是,他们通常在错误的地方进行修复。由于正常工作的部分通常只是偶然地工作,因此假设某些东西已损坏而尝试修复系统通常会导致将正确的设置更改为不正确的设置。
获得清晰解决方案的第一步是准确了解哪些终端有偏差,哪些没有。通常,它们都表现得像控制台一样,在这种情况下,使一切正常工作的修改是最小的。但是,如果您有一些有偏差的终端(例如,gnome-terminal 的有偏差版本),您将不得不以特殊的方式对待它。
以下 C 单行代码
void main(void) {int c; while(c = getchar()) printf("%d 0x%02X\n", c, c);} |
如果您有一些有偏差的终端模拟器,则必须将其与标准模拟器区分开来。从理论上讲,这不应该是一个问题,因为终端数据库中对于具有不同序列的终端有不同的条目(使用的条目取决于TERM变量的值)。
在这里,我们采用的方法是gnome条目应该用于所有有偏差的 VT100 模拟器,而xterm条目用于标准模拟器。这与几个发行版一致(少数情况除外,例如 RedHat ≤5.0,其中xterm条目是有偏差的)。
但是,gnome-terminal 默认使用与 xterm 相同的条目,因此如果一个有偏差而另一个没有,则您需要找到一种方法来区分它们。选项termname的 gnome-terminal 允许用户设置TERM变量为一个更合理的名称。但是,在旧版本的 gnome-terminal 中,此选项不起作用。而且,有时不容易修改 gnome-terminal 的启动方式。
这里的一个好主意是利用 gnome-terminal 设置了COLORTERM变量为gnome-terminal。因此,通过向 shell 配置文件添加一个简单的测试,我们可以修复TERM变量。
我们现在的问题是终端数据库可能缺少一个gnome用于有偏差终端的条目(这发生在许多 termcap 和 terminfo 版本上)。最近的 terminfo 数据库有一个条目gnome,但是,在任何情况下,由于 gnome-terminal 的行为基本上类似于 xterm 模我们著名的两个键,因此可以自动生成一个全新的正确条目。
由 bash 和许多其他程序用于读取输入行的 readline 库可以自定义,以便识别特定的字符序列。自定义还可以取决于TERM变量,因此一旦我们可以区分终端,我们就可以对键盘进行微调。
此外,如果您希望 less 和其他执行原始行输入的应用程序正常工作,则必须使 shell 确信,在有偏差的终端模拟器下,擦除字符是 BS,而不是 DEL (在另一种情况下,Backspace 键已经发出 DEL,因此我们不必做任何事情)。这可以使用 stty 命令完成。
![]() | 这些修复程序有一些缺点。首先,它们仅适用于指定的终端。其次,理论上(但这不太可能发生)它们可能会混淆其他终端上的 readline 库。然而,这两个限制基本上是无害的。 |
首先,使用 infocmp gnome 检查您是否已经有一个gnome条目在您的 terminfo 数据库中(我们稍后将修复 termcap)。如果该条目不存在,则以下命令
bash$ tic <(infocmp xterm |\ sed 's/xterm|/gnome|/' |\ sed 's/kbs=\\177,/kbs=^H,/' |\ sed 's/kdch1=\\E\[3~,/kdch1=\\177,/') |
现在,将以下代码片段添加到~/.inputrc[1]:
"\e[3~": delete-char |
$if term=gnome DEL: delete-char Meta-DEL: kill-word "\M-\C-?": kill-word $endif |
请注意,条件赋值使有偏差的终端模拟器能够工作,前提是 TERM 变量设置正确。为了保证这一点,有许多技术。首先,由于TERMgnome-terminal 的变量的默认值为xterm,如果所有终端都没有偏差,那么我们什么也不做。但是,如果默认使用xterm条目的终端有偏差,则您必须找到一种方法来设置TERM变量;例如,假设这对于 gnome-terminal 是正确的。
获得此效果的最简单方法是使用参数启动 gnome-terminal--termname=gnome,例如,通过在 GNOME 面板上的启动器中适当地设置命令行。但是,如果您有旧版本,并且此方法不起作用,则可以添加以下行
if [ "$COLORTERM" = "gnome-terminal" ] then export TERM=gnome fi |
![]() | 将终端设置为gnome可能会阻止 ls 使用颜色,因为许多版本的 ls 不知道 gnome-terminal 具有颜色功能。为了避免这个问题,请创建一个配置文件~/.dircolors,使用 dircolors --print-database >~/.dircolors,并添加一行TERM=gnome到配置文件。 |
我们现在将动态生成一个适合有偏差的终端模拟器的 termcap 条目;这可以按如下方式完成,始终在~/.bashrc:
if [ "$TERM" = "gnome" ] then export TERMCAP=$(infocmp -C gnome | grep -v '^#' | \ tr '\n\t' ' ' | sed 's/\\ //g' | sed s/::/:/g) fi |
最后,我们必须向终端设备解释擦除键生成哪个字符。由于通常擦除键应执行退格操作,因此有一个从 Red Hat 借鉴来的巧妙技巧/etc/bashrc,它有效:将此添加到~/.bashrc:
KBS=$(tput kbs) if [ ${#KBS} -eq 1 ]; then stty erase $KBS; fi |
![]() | 某些发行版可能已经在系统范围内的/etc/inputrc配置文件中进行了修复。在这种情况下,您可以从您的~/.inputrc. |
在 tcsh 的情况下,所有修复都放在~/.tcshrc中,并遵循与 bash 的修复程序相同的原理
bindkey "^[[3~" delete-char if ($?COLORTERM) then if ($COLORTERM == "gnome-terminal") then setenv TERM gnome endif endif if ($?TERM) then if ($TERM == "gnome") then setenv TERMCAP \ "`infocmp -C gnome | grep -v '^#' | tr '\n\t' ' ' | sed 's/\\ //g' | sed s/::/:/g`" bindkey "^?" delete-char bindkey "^[^?" delete-word bindkey "\377" delete-word endif endif set KBS=`tput kbs` if (${%KBS} == 1) then stty erase $KBS endif |
[1] | 在旧版本的 bash 上,您必须记住设置INPUTRC,例如添加
| |
[2] | 更准确地说,是指在每个 shell 而不仅仅是登录 shell 中读取的 shell 配置文件。正确的文件取决于您的 bash 的启动顺序。 |