AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 444214
Accepted
Zackary
Zackary
Asked: 2018-05-17 09:48:05 +0800 CST2018-05-17 09:48:05 +0800 CST 2018-05-17 09:48:05 +0800 CST

bash:Shift+箭头键使A、B、C、D

  • 772

使用 bash shell 时,我尝试使用Shift+LEFT突出显示并复制我输入的命令(而不是使用鼠标)。但是,我得到了很多C。后来我意识到Shift+UP使A,Shift+DOWN使B,Shift+RIGHT也使D。

为什么会这样?

我认为它来自原始击键数据(^[[A、^[[B、^[[C和^[[D),但它只是一个大写字母(^[[开头没有)。

bash arrow-keys
  • 2 2 个回答
  • 9993 Views

2 个回答

  • Voted
  1. JdeBP
    2018-05-17T17:23:36+08:002018-05-17T17:23:36+08:00

    这是一个可以追溯到 1980 年代的键盘输入协议,而您的外壳,而不是M. Vazquez-Abrams 的回答中的“终端驱动程序”(应该是什么),没有正确处理它。此外,它是一个完全有效的控制序列。

    背景

    终端发出功能键和扩展按键的控制序列。它们可以发出 DECFNK 控制序列,这是 CSI 引入的控制序列;Linux 功能键控制序列,这是一种不同的 CSI 引入序列;SCO控制台功能键控制序列,是CSI引入的第三种序列;移位的单个字符,以 SS3 为前缀;或者,在这种情况下,各种事物的 ECMA-48 标准序列。

    (SS3 和 CSI 是控制字符,在 C1 范围内。Single Shift 3 和 Control Sequence Introducer。)

    您的(IBM M 型类似或类似的)键盘上有两个特定的小键盘,一个计算器小键盘和一个光标小键盘。DEC VT 风格的终端仿真器(您可能会遇到的大多数终端仿真器,从内核中的终端仿真器到 unicode-rxvt)所采用的模型是两个键盘都有可单独切换的应用程序/正常模式。全屏 TUI 应用程序,使用 libedit 或 GNU readline 库(或 ZLE)的东西,例如你的 shell,以及一些其他类型的应用程序指定他们想要的模式,然后通过读取突发来监听来自终端的控制序列字符数(因为人类无法像终端或终端仿真器发送控制序列一样快地键入完整的 ECMA-48 控制序列,Esc来自终端仿真器的键发送以 ␛ 字符开头的控制序列)。

    • 在应用程序模式下,每个键盘上的箭头键会产生以 SS3 为前缀的移位单个字符。修饰符不能真正产生任何效果(尽管 XTerm 搞砸了),因为 ECMA-35 和 ECMA-48 将 SS2 和 SS3 定义为仅作用于单个后续字符。但是,另一方面,计算器和光标键盘会生成不同的 SS3 移位字符,从而可以将两个键盘区分开来。
    • 在正常模式下,每个键盘上的箭头键产生相同的CSI 引入的控制序列,它们是来自 ECMA-48 的那些,带有来自 DEC VTs 的增强。特别是,光标键发送 ECMA-48 控制序列 CUU、CUD、CUR 和 CUL(CUrsor Up、CUrsor Down、CUrsor Right 和 CUrsor Left)。ECMA-48 控制序列的 DEC 增强是控制序列包括当前修改器状态。

    因此,人们可以在应用程序模式和普通模式之间进行选择,在这种模式下,人们无法知道按下了哪些修饰符,但可以区分两个左箭头键,而在普通模式下,人们无法区分两个箭头键,但可以知道按下了哪些修饰符。

    更详细地说:ECMA-48 控制序列的 DEC 增强是控制序列有两个参数:

    • 根据 ECMA-48,第一个参数类似于 CUU、CUD、CUR 或 CUL 实际可以具有的第一个参数。它是出现次数,因此始终为 1。
    • 第二个参数是有趣的。它包含修饰键状态,它(由于涉及 CSI 引入的控制序列中的参数在省略时如何工作的原因)是一组用于各种修饰键的位标志,加上 1,编码为十进制数。

    这就是 DEC VT 终端自 1980 年代以来一直在做的事情。近年来,一些终端仿真器终于引入了相同的功能(尽管如前所述,XTerm 搞错了)。

    这是怎么回事。

    问题是您的 GNU readline 库、libedit、ZLE 等并没有真正正确地处理协议。他们不应该完全受到责备。他们依赖于 termcap 和 terminfo 系统,这根本不能胜任这里的工作。termcap 和 terminfo 并没有真正的输入控制序列可以变化的概念,更不用说多模式键盘了。

    为此,您必须查看 Vim 之类的东西,它可以使用对 terminfo 的特殊覆盖进行编程,以指定遵循上述协议(参见:help xterm-modifier-keysVim 中)的控制序列,或使用Paul Evans 的 libtermkey及其CSI 驱动程序的 NeoVIM 。libtermkey 的 CSI 驱动程序是一个必须正确处理来自 DEC VT 类似终端仿真器的键盘输入的方法。它是一个实际的 ECMA-48 状态机解析器,可以正确解码控制序列。

    但是你的 shell 正在做的是在 terminfo 中查找箭头键的条目,并且只匹配那些特定的控制序列。

    具体来说:

    • 您的 shell 正在kcub1其 terminfo 记录中查找您的终端的功能。这是记录中的一个,teken例如:
      % tput -T teken kcub1|hexdump -C
      00000000 1b 5b 44 |.[D|
      00000003
      %
    • 它仅将特定输入序列匹配为← Left Arrow.
    • 当您按⇧ Level 2 Shift+时,← Left Arrow您的终端仿真器正在发送控制序列 CSI 1 ; 2 D。相反,它使用 7 位替代方案和发送␛ [ 1 ; 2 D,这␛ [是将 CSI 编码为 7 位字符的方式。
    • 您的 shell 无法将其与来自 terminfo 的任何已知固定输入序列匹配,并中止处理。在我的 Bourne Again shell 上,它最终吞下了前两个字符并表现得好像我按下了; 2 D。在您的 Bourne Again shell 上,它最终会吞下前四个字符并表现得好像您按下了D。

      什么故障模式取决于它尝试模式匹配的输入序列集,因为这决定了它在确定它有一个没有可能匹配的序列之前吞下了多少个字符。当然,这又取决于您的终端的 terminfo/termcap 记录实际包含的内容以及您告诉 shell 您的终端是什么终端类型。

    修复

    这类事情的本地修复是在你的 shell 中使用键绑定来获得创意。这就是为什么,例如,你会发现人们在他们.zshrc的 s 中使用 Z shell 做这种事情:

    bindkey "\e[1;5D" 后向词
    bindkey "\e[1;5C" 正向字

    不幸的是,没有非本地修复。这将涉及非常显着地重新架构你的 shell 的输入处理。这种重新架构早就该进行了。(见证 NeoVIM。)但是还没有人解决它。

    进一步阅读

    • 字符代码结构和扩展技术 。ECMA-35。第 6 版。1994.ECMA 国际。
    • 编码字符集的控制功能。ECMA-48。第 5 版。1991.ECMA 国际。
    • “ANSI、短 ANSI 和 PC 键盘代码”。 VT420 程序员参考手册。EK-VT420-RM-002。1992 年 2 月。数字。
    • DECFNK. “ANSI 控制功能”。 VT510 终端程序员信息。EK-VT510-RM。1993 年 11 月。数字。
    • VT520/VT525 视频终端编程器信息。EK-VT520-RM。1994 年 7 月。数字。
    • https://github.com/fish-shell/fish-shell/issues/2139#issuecomment-388706768
    • https://unix.stackexchange.com/a/238932/5132
    • 13
  2. Best Answer
    Ignacio Vazquez-Abrams
    2018-05-17T09:53:48+08:002018-05-17T09:53:48+08:00

    按Ctrl+V将使下一个按键按字面意思输入。对于Shift+↑这将导致“^[[1;2A”。终端驱动程序使用“^[[1;2”作为无效的转义序列,只留下“A”。

    • 3

相关问题

  • 通过命令的标准输出以编程方式导出环境变量[重复]

  • 从文本文件传递变量的奇怪问题

  • 虽然行读取保持转义空间?

  • `tee` 和 `bash` 进程替换顺序

  • 运行一个非常慢的脚本直到它成功

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    ssh 无法协商:“找不到匹配的密码”,正在拒绝 cbc

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    如何卸载内核模块“nvidia-drm”?

    • 13 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add 返回:“连接代理时出错:没有这样的文件或目录” 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve