![bash 的元键是什么?](https://linux22.com/image/20363/bash%20%E7%9A%84%E5%85%83%E9%94%AE%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F.png)
我尝试使用xmodmap
映射META_L到MENU键,但它似乎没有被接受bash
为元键。所以,我想知道这些组件(键盘、X、xterm、bash)在元键和超级键方面如何相互关联。任何解释将不胜感激。
让我换一种说法。例如,bash 手册页显示,函数 yank-nth-arg 已绑定,M-C-y并且当我按 时它会起作用Esc-Control-y。但我觉得这有点麻烦。那么我怎样才能让 bash 接受另一个键作为它的所有默认绑定Meta(如)?Menu
答案1
Meta
从键盘按键到修饰符(例如和 )的映射Control
由 X 服务器(即 GUI 的低级部分)处理。可以通过旧式来操纵此映射xmodmap
命令或新式XKB界面,或通过在幕后使用其中之一的 GUI 配置工具。
默认情况下,在大多数设置中,该Meta
键是标记为 的键Alt。这是因为从历史上看,许多 UNIX 工作站都有一个标记为 的密钥,Meta而 PC 则有一个标记为 的密钥Alt。因此,如果您有 的绑定M-C-y
,请按Ctrl+ Alt+ Y。
要检查当前的绑定是什么,请xev
在终端中启动该程序。当 xev 窗口聚焦时,按键;您将在终端中看到生成的事件的记录。
终端仿真器(或物理终端对应的终端设备)与应用程序之间的通信使用字符。当您按下 时A,终端会收到信息“ A
key, nomodifier”,但它发送给终端中运行的应用程序的是字符a
。当您按下Up或等功能键时F1,没有对应的字符;终端发送以转义字符(字节 27,有时写为\e
或^[
)开头的字符序列。当终端模拟器(例如 xterm)收到带有Meta
修饰符的按键事件时,它会将该键转换为转义字符,后跟该键的基础功能,例如,当您按+\ea
时(转义,小写 a)。MetaA
“终端”、“shell”、“tty”和“控制台”之间的确切区别是什么?可能是有用的背景。
答案2
按键事件由 X 服务器生成(如 所配置xmodmap
),并发送到您的 X 应用程序。您的窗口管理器可以在将其发送到 xterm 之前拦截它。 XTerm 反过来将事件转换为一些字节,并将这些字节发送到由您的 shell bash 分配的伪 tty。
请注意,并非所有事件都会被 XTerm 直接转换为字节。例如,Ctrl和shift键本身生成 X 键盘事件,但 XTerm 发送没有什么到在其中运行的 shell(或其他应用程序)。这还包括Meta密钥本身,但不包括Menu密钥。但是,按Meta-生成的事件e将使 XTerm 发送字节 0xE5 或两字节序列 0x1B 0x65,具体取决于 XTerm.VT100.metaSendsEscape 资源设置。
答案3
巴什的元键最初是这样定义的(lib/readline/ChangeLog
):
Mon Jul 13 11:34:07 1992 Brian Fox (bfox@cubit)
* readline.c: (rl_variable_bind) New variable "meta-flag" if "on"
means force the use of the 8th bit as Meta bit. Internal variable
is called meta_flag.
这恰好是它的解释方式恩诅咒和xterm。 A很少为使此功能成为可选而提供的终端(这方面并不普遍。您将遇到的大多数终端都使用硬编码行为(并且不是很有趣)。术语信息手册页记录了这些终端功能:
has_meta_key km km Has a meta key
(i.e., sets 8th-bit)
meta_off rmm mo turn off meta mode
meta_on smm mm turn on meta mode
(8th-bit on)
并解释了该功能:
如果终端具有充当移位键的“元键”,设置所传输的任何字符的第 8 位,则可以用 来指示这一事实
km
。否则,软件将假定第 8 位是奇偶校验位,并且通常会被清除。如果存在用于打开和关闭此“元模式”的字符串,则可以将它们指定为smm
和rmm
。
Alt
一些终端仿真器中并入了一个不同的功能,即在响应键时添加转义字符前缀。 Bash(实际上是readline
库)记录了其用法变更日志从 2004 年开始:
lib/readline/callback.c
- use _rl_dispatch_callback and a chain of _rl_keyseq_contexts to
simulate the recursion used to decode multicharacter key sequences
(even things like ESC- as meta-prefix
Meta 是一个特例修饰语钥匙。与control和一样shift,您与另一个键同时按下它,并期望看到与单独按下该键不同的东西。 X 通过在键的 X 事件中传递的修饰符值中分配一个位来提供修饰键。按键可以是多个X事件; X 提供了组合这些事件同时保留修饰符的函数。
X 还为键盘上可能出现的每个键定义了符号。它通过在组合事件的函数中进行特殊处理来提供其他值(例如 Unicode)。
但“元”是一个特例。
X 应用程序没有meta密钥,除非按照惯例。 X 没有元键或元修饰符的定义。按照惯例,终端会查找Alt-key 和/或已知的修饰符之一xmodmap
,例如,mod2
。后来的xkb该功能通过提供另一层信息来查找密钥,从而使事情变得复杂(但相对于本讨论没有提供任何改进)Alt。
惯例当然只能带你到目前为止,因为你既不知道xmodmap
也不xkb
知道任何具体的事情元。例如,xterm 是可配置的,但并非所有用户都想要配置元以同样的方式。例如,Alt可能不是预期的元密钥,例如,如果它在translation
资源中使用的话。另一个键可能是元键,但用户(特别是在 bash 中使用转义序列的用户)可能希望在按下 时发送转义字符Alt。但请记住,除非将其配置为修饰语这些都不会发生:xterm 本身不会组合事件。
xterm 有几个资源设置(记录在手册页):
altIsNotMeta
和altSendsEscape
(添加到2007年)。eightBitInput
自从2006年对应于元模式的原始含义,并且为此定义了一个转义序列,它提供了smm
和rmm
(设置/删除元模式)终端功能。eightBitInput
被修改于2003年通过将解码的 Unicode 值移动 128 而不是原始输入字节来考虑 UTF-8。metaSendsEscape
日期从1999年eightBitInput
比 更老metaSendsEscape
。这已经实现了之间的选择元模式(添加第八位)或在密钥前添加escape自 X11R4 (1989) 以来的前缀。但该功能是在启动时确定的:在初始化期间检查以确定输入是否设置为允许 8 位或仅允许 7 位。此后,它没有改变。
有些人将两者等同起来(第 8 位和转义前缀),将后者称为元模式。根据您对此事的看法,eightBitInput
xterm 的资源设置是获取可用元密钥的解决方案的一部分。
进一步阅读: