bash - 复杂的提示符

bash - 复杂的提示符

我想要一个非常复杂的提示。它应该包含登录名、计算机名称、日期、时间、工作目录、最后一个命令的结果和换行符。我也想为每件物品上色。所以我插入了我的.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}] "

...

等等..你看到了吗?这样更容易知道发生了什么。

相关内容