我想要一个非常复杂的提示。它应该包含登录名、计算机名称、日期、时间、工作目录、最后一个命令的结果和换行符。我也想为每件物品上色。所以我插入了我的.bashrc
某种怪物,如下所示:
# login and computer name
PS1='[\e[1;37m\]\u\e[m\]@\e[1;32m\]\h\e[m\]] '
# date, time and working directory
PS1=$PS1'[\e[1;34m\]\D{%Y-%m-%d} \e[1;35m\]\t\e[m\]] \e[1;33m\]\w\e[m\] '
# result of last command and command prompt in new line
PS1=$PS1'\e[1;31m\]${?#0}\e[m\]\n \e[1;36m\]\$\e[m\] '
我确实知道这是一个糟糕的解决方案,但我对 bash 的经验太少,无法改进它。但这并不是唯一的问题。
$ aaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bash: bbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: command not found...
最后一次a
按下Home
键后,但视觉插入符没有转到命令的开头。正如您所看到的,实际的插入符号位于开头。为什么会出现这种情况?如何改进我的命令提示符.bashrc
?
更新:
使用@Groxxda 的建议后,我又遇到了一个问题。我的.bashrc
PS1
定义看起来像这个。现在不会出现所描述的问题。但是,如果在我的命令历史记录中我有ls
,在此之前我有cat script.sh
,并且如果我向上推箭头两次,我会得到类似命令cat scls
并且缓冲区只有两个符号(只有ls
)。为什么会出现这种情况?我该如何处理这个问题?
答案1
您需要将提示文本的不可见部分括在\[
和中\]
。
它用于bash
计算完整提示的长度,因此可以确定打印后光标的位置。
例如,ANSI 颜色转义代码是不可见的 - 它们会更改稍后输出的文本的颜色。它们需要像这样封闭:
\e[1;35m
变成\[\e[1;35m\]
在您的更新中,您写道这有帮助,但还有另一个问题:如果您将历史记录与/
一起使用,则屏幕不会在正确的位置被清除。UpDown
这只是第一个问题的另一个方面:提示文本长度的计算是错误的。
让我们看一下链接中更正后的提示文本:
# login and computer name
PS1='[\e[\[1;37m\]\]\u\e[\[m\]\]@\e[\[1;32m\]\]\h\e[\[m\]\]] '
# date, time
PS1=$PS1'[\e[\[1;34m\]\]\D{%Y-%m-%d} \e[\[1;35m\]\]\t\e[\[m\]\]] '
# working directory and result of last command
PS1=$PS1'\e[\[1;33m\]\]\w\e[\[m\]\] \e[\[1;31m\]\]${?#0}\e[\[m\]\]\n '
# command prompt
PS1=$PS1'\e[\[1;36m\]\]\$\e[\[m\]\] '
问题是\[
和\]
没有包含整个颜色转义序列:
提示符以
[\e[\[1;37m\]\]...
这里的颜色转义序列是\e[1;37m
。所以转义字符\e
和[
都在外面。至少[
会被算作可见。另外,有两个关闭\]
- 它可能不会引起问题,但至少令人困惑 - 它们不能嵌套。
正确的写法是:
[\[\e[1;37m\]...
其他颜色转义序列也有同样的问题。
答案2
您应该将其模块化 - 这将使跟踪变得更容易:
CS='\[\033[1;3' CE='m\]'
WT=${CS}7${CE} LB=${CS}6${CE} PR=${CS}5${CE} \
DB=${CS}4${CE} YL=${CS}3${CE} GN=${CS}2${CE} RD=${CS}1${CE}
CE='\[\033[m\]' CS=
现在你做你的事情:
# login and computer name
PS1="[${WT}\u${CE}@${GN}\h${CE}] "
...
等等..你看到了吗?这样更容易知道发生了什么。