系统:Debian 8 with XFCE,Cli:Konsole Version 2.14.2(终端称为“Konsole”-> https://konsole.kde.org/)
我的朋友让我帮他解决一个奇怪的问题。
一些键有一个奇怪的行为。
例如Shift + §
使当前行只显示(arg: 0)
(我们有一个瑞士键盘https://en.wikipedia.org/wiki/QWERTZ#/media/File:KB_Swiss.svg,你可以在左上角找到这个键)
按ö
给出(arg: 6)
。等等...
我可以通过以下命令摆脱这种“模式”:
set -o vi
set +o vi
Run Code Online (Sandbox Code Playgroud)
但我之前不是在 vi 模式下。据我所知。但似乎有些东西被“重置”了。问题是,如果我使用上面的两个命令,我也会丢失一些我想要的设置。
编辑:我忘了提及;在另一个终端模拟器上——UXTerm
行为是“正常的”。所以我想要的方式。但是在XTerm
我有与 in 相同的行为Konsole
。
EDIT2:根据要求:
user@myMachine:~$ bind -p | grep arg
"\M--": digit-argument
"\M-0": digit-argument
"\M-1": digit-argument
"\M-2": digit-argument
"\M-3": digit-argument
"\M-4": digit-argument
"\M-5": digit-argument
"\M-6": digit-argument
"\M-7": digit-argument
"\M-8": digit-argument
"\M-9": digit-argument
"\M-.": insert-last-argument
"\M-_": insert-last-argument
# universal-argument (not bound)
# vi-arg-digit (not bound)
# vi-yank-arg (not bound)
"\M-.": yank-last-arg
"\M-_": yank-last-arg
"\M-\C-y": yank-nth-arg
bioinf@ags-wav-debian-MandS:~$ set +o emacs
bioinf@ags-wav-debian-MandS:~$ bind -p | grep ö
bash: bind: warning: line editing not enabled
Run Code Online (Sandbox Code Playgroud)
附加信息:
user@machine:~$ locale charmap
ANSI_X3.4-1968
user@machine:~$ bind -v | grep meta
set convert-meta on
set enable-meta-key on
set input-meta on
set meta-flag on
set output-meta on
Run Code Online (Sandbox Code Playgroud)
这似乎都归结为您的语言环境中的字符集是 ASCII 的事实。ASCII 是 60 年代的美国字符集,它是大多数现代字符集的公分母。
这通常发生在语言环境未配置(LANG、LC_* 环境变量均未设置)或设置为C
或 时POSIX
。
该字符集定义了 128 个字符,字节值为 0 到 127。构成 sh 语言并在大多数命令名称中找到的所有字符都是 ASCII。但是 § 和 ° 不是。
现在这些符号在你的键盘上,当你在终端模拟器中输入时会发生什么?
如果您在字符集为 ASCII 的语言环境中启动终端仿真器,则是在告诉终端仿真器当您按下 时A,(XK_a
X11 按键事件)它需要以a
ASCII 编码发送字符的编码,即 0x61。但是当你按下Shift+§(XK_degree
X11 keypress event)时,它应该发送°字符的编码,但是ASCII中没有这样的字符,那么它应该怎么做?
xterm
并rxvt
选择发送°
iso-8859-1字符集中的编码。这是大多数西方世界的 8 位字符集(扩展 ASCII 以涵盖德语、法语、英国英语、西班牙语等语言中使用的大多数字符)。在 UTF-8 之前,这是最常用的字符集。
My konsole
,Eterm
并xfce4-terminal
发送?
每个非 ASCII 字符。
我的 gnome 终端和终结器发送°
.
当bash
接收到°
(0xb0)的iso8859-1编码时xterm
,它会做什么?
我们已经告诉它字符集是 ASCII,因此 0xb0 对应于没有已知字符。
在美国的过去,Ctrl+X用于输入从 0 到 31(控制字符)的字符。在 ASCII 中,这将发送相应字符的低 5 位。例如,A
being 0x41
,a
being 0x61
,Ctrl+A将发送0x61 & 0x1f,所以0x1(^A
又名CA字符)。虽然Meta+X会发送x
第 8 位设置的编码。a
是0x61
,Meta+A会发送 0x61 | 0x80,即0xe1。按Meta+0将发送 0x30 | 0x80,即 0xb0 也称为 M-0(非)字符。
在 ASCII 中,0x0 -> 0x1f 用于电传打字机时代的控制字符,其中大部分不再使用,并且不使用 0x80 到 0xff,因此这是一种输入代码的方法,可以用来做其他事情输入文字。例如,emacs 使用那些用于编辑键的C-B
字符,字符将光标向左移动一个字符,M-B
(非)字符将光标向左移动一个字。
如今,由于大多数人使用通过使用字节值 0x80 到 0xff 来扩展 ASCII 的字符集,因此它们不再通常被理解为那些元字符。Meta+X现在通常会发送两个字符:ESC 和 X 字符。
尽管如此,当在字节值 0x80 到 0xff 不可能是字符的语言环境中,当bash
(实际上readline
)从 0xb0 等 tty 设备读取字节值时,它会将其理解为 M-0(默认情况下绑定到digit-argument
,这解释了您的arg: 0
)。
这是convert-meta
readline 配置中的设置。您会在 readline 文档 ( man 3 readline
) 中发现,当 readline 检测到字符集是 7 位时,它会将其设置on
为将这些 0xb0 字节转换为 ESC + 0。
如果你关闭它:
bind 'set convert-meta = off'
Run Code Online (Sandbox Code Playgroud)
(并假设input-meta
和output-meta
也是on
)。然后你会发现按下°
会让你°
显示出来。但这将是一个 0xb0 iso8859-1 编码,°
其中应用程序不知道该怎么做。
您需要做的是将语言环境修复为具有这些°
字符的语言环境。现在,您应该只考虑 UTF-8,因为它涵盖了所有字符并且得到了广泛支持。
所以,请检查您的桌面配置为你的国际化设置,并选择像de_CH.UTF-8
/ fr_CH.UTF-8
/ it_CH.UTF-8
(德国/法国/意大利来说瑞士法郎,UTF-8字符集)最适合您的环境相匹配。
您可能需要注销并再次登录才能完全考虑到这一点。
某些登录管理器有时也允许您在登录时通过一些下拉菜单选择区域设置。