$PS1 修改后 - 光标跳至 bash 提示符左侧

$PS1 修改后 - 光标跳至 bash 提示符左侧

我修改了我的$PS1变量。

问题$现在,当我通过 滚动浏览 bash 历史记录时,光标跳到左侧Arrow-UP

在此输入图像描述

这就是我的$PS1现在。

admin@OLAF:~$ declare -p PS1
declare -- PS1="\\[\\e]0;\\u@\\h: \\w\\a\\]\${debian_chroot:+(\$debian_chroot)}\\[\\e[1m\\e[38;5;208m\\e[48;5;24m\\u@\\h\\[\\e[0m\\]:\\[\\e[97m\\]\\w\\[\\e[0m\\]\\\$ "

答案1

为了正确管理光标,shell 需要知道提示字符串的哪些部分实际上会导致光标前进,哪些部分不会。

为此,提示中不产生可见字符的任何部分都应该用\\[...封装\\]

请注意,提示格式化最终发生在多个阶段:提示扩展代码和 shell 变量由 shell 本身处理,但颜色和格式代码仅传递到终端模拟器,这是一个单独的过程。

您的提示如下:

declare -- PS1="\\[\\e]0;\\u@\\h: \\w\\a\\]\${debian_chroot:+(\$debian_chroot)}\\[\\e[1m\\e[38;5;208m\\e[48;5;24m\\u@\\h\\[\\e[0m\\]:\\[\\e[97m\\]\\w\\[\\e[0m\\]\\\$ 
  • \\[- 开始非生产性部分
  • \\e]0;\\u@\\h: \\w\\a- 这部分更改支持此功能的终端仿真器中的窗口标题,因此这些都不会成为实际提示的一部分。
  • \\]- 结束非生产部分
  • \${debian_chroot:+(\$debian_chroot)}- 如果$debian_chroot变量已设置且非空(即 shell 位于 chroot 环境中),则在括号内输出其值;否则输出空字符串。这些扩展完全在 shell 内处理,因此 shell 始终知道这部分的长度。
  • \\[- 开始另一个非生产性部分
  • \\e[1m\\e[38;5;208m\\e[48;5;24m- 设置粗体;设置8位前景色;设置8位背景颜色。这些是有效的非打印格式代码。
  • 这里应该有一个“结束非生产部分”代码,但它丢失了!
  • \\u@\\h- 这将产生文本admin@OLAF,即用户名@主机名。
  • \\[\\e[0m\\]- 正确封装“重置为默认输出”代码
  • :- 只输出一个冒号
  • \\[\\e[97m\\]- 正确封装“设置明亮的前景色”代码
  • \\w- shell提示符扩展:输出当前工作目录
  • \\[\\e[0m\\]- 正确封装“重置为默认输出”代码
  • \\\$- shell 提示符特殊扩展:$如果是普通用户,或者#如果是 root,则输出。

因此,由于缺少代码,shell 假定字符串“admin@OLAF”(由 shell 从 展开\\u@\\h)成为格式化代码的一部分,并且最终会出现在实际提示符之外的其他位置。该字符串的长度为 10 个字符,因此当 shell 需要在提示后重新编写命令时,它会错误地计算要移动到的列,准确地说是 10 个字符。

答案2

有一个失踪了\\]此处的分隔符:

\\[\\e[1m\\e[38;5;208m\\e[48;5;24m\\u@\
                                  ^^

相关内容