![Bash 似乎处于特殊模式](https://linux22.com/image/112675/Bash%20%E4%BC%BC%E4%B9%8E%E5%A4%84%E4%BA%8E%E7%89%B9%E6%AE%8A%E6%A8%A1%E5%BC%8F.png)
系统:带有 XFCE 的 Debian 8,Cli:Konsole 版本 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
但我之前不是vi模式。据我所知。但似乎有些东西被“重置”了。问题是,如果我使用上面的两个命令,我也会丢失一些我想要的设置。
编辑:我忘记提及的是;在另一个终端模拟器上 - UXTerm
- 行为是“正常”的。所以按照我想要的方式。但在XTerm
我有同样的行为Konsole
。
编辑2:正如所要求的:
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
附加信息:
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
答案1
似乎一切都归结为这样一个事实:您的语言环境中的字符集是 ASCII。 ASCII 是 60 年代的美国字符集,是大多数现代字符集的共同点。
当未配置语言环境(LANG、LC_* 环境变量全部未设置)或将它们设置为C
或时,通常会发生这种情况POSIX
。
该字符集定义了 128 个字符,字节值为 0 到 127。构成 sh 语言以及在大多数命令名称中找到的所有字符都是 ASCII 格式。但 § 和 ° 则不然。
现在这些符号都在您的键盘上,当您在终端模拟器中键入它时会发生什么?
如果您在字符集为 ASCII 的语言环境中启动终端仿真器,则您将告诉终端仿真器,当您按下 时A(XK_a
X11 按键事件),它需要发送a
ASCII 编码中的字符编码,即 0x61。但是当你按下Shift+§(XK_degree
X11按键事件)时,它应该发送°字符的编码,但ASCII中没有这样的字符,那么它应该做什么?
xterm
并选择发送iso-8859-1字符集中rxvt
的编码。°
这是大多数西方世界的 8 位字符集(扩展 ASCII 以涵盖德语、法语、英式英语、西班牙语等语言中使用的大部分字符)。在 UTF-8 之前,这是最常用的字符集。
My konsole
,Eterm
并xfce4-terminal
发送?
每个非 ASCII 字符。
我的 gnome-terminal 和 terminator 发送°
.
当收到像中这样的(0xb0)bash
的iso8859-1编码时,它会做什么?°
xterm
我们已经告诉它字符集是 ASCII,因此 0xb0 对应于未知字符。
过去在美国,Ctrl+X用于输入 0 到 31 的字符(控制字符)。在 ASCII 中,这将发送相应字符的低 5 位。例如,A
being 0x41
、a
being0x61
会Ctrl+A发送 0x61 和 0x1f,因此 0x1(^A
又名 CA 字符)。同时将发送第 8 位设置Meta+X的编码。 ,会发送 0x61 | 0x80,即0xe1。按下将发送 0x30 | 0x80,即 0xb0 也称为 M-0(非)字符。x
a
0x61
Meta+AMeta+0
在 ASCII 中,0x0 -> 0x1f 用于电传打字机时代的控制字符,其中大多数已不再使用,并且 0x80 到 0xff 也不再使用,因此这是一种输入代码的方法,可用于执行除输入文字。例如,emacs 使用这些键作为编辑键,C-B
字符将光标向左移动一个字符,M-B
(非)字符将光标向左移动一个单词。
如今,由于大多数人使用通过使用字节值 0x80 到 0xff 来扩展 ASCII 的字符集,因此这些字符集不再被普遍理解为元字符。Meta+X现在通常发送两个字符:ESC 和 X 字符。
尽管如此,当在字节值 0x80 到 0xff 不可能是字符的语言环境中时,当bash
(实际上readline
)从 tty 设备读取字节值(如 0xb0)时,它会将其理解为 M-0(默认情况下绑定到digit-argument
,这解释了你的arg: 0
)。
这是convert-meta
readline 配置中的设置。您会在 readline 文档 ( man 3 readline
) 中发现,当 readline 检测到字符集是 7 位时,它会将其设置为on
将那些 0xb0 字节转换为 ESC + 0。
如果您使用以下命令将其关闭:
bind 'set convert-meta = off'
(并且假设input-meta
和output-meta
也是on
)。然后你会发现按下°
就会°
显示一个。但这将是 0xb0 iso8859-1 编码,°
应用程序将不知道该如何处理。
您需要做的是将区域设置修复为具有这些°
字符的区域设置。如今,您应该只考虑 UTF-8,因为它涵盖了所有字符并且得到了广泛支持。
因此,请检查您的桌面配置的国际化设置,并选择最适合您的环境的设置,例如de_CH.UTF-8
/ fr_CH.UTF-8
/ (瑞士德语/法语/意大利语,使用 UTF-8 作为字符集)。it_CH.UTF-8
您可能需要注销并再次登录才能充分考虑到这一点。
某些登录管理器有时还允许您在登录时通过某些下拉菜单选择区域设置。