答案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@\
^^