在我的系统上,当使用彩色提示时,如果输出的最后一个字符不是换行符,则前一个命令输出的最后一行将被覆盖。
例如:使用默认的、非彩色的 bash 提示符,我们有:
[myusername@myhostname 目录名]$ echo -n foo-bar foo-bar[我的用户名@我的主机名 目录名]$
这是预料之中的。
但是,使用以下彩色提示:
PS1='\[\033[1;32m\]\u@\h\[\033[0m\]:\[\033[1;34m\]\w\[\033[0m\]\$ '
我们有(这里显示没有颜色):
myusername@myhostname:~/path/to/dirname$ echo -n foo-bar myusername@myhostname:~/path/to/dirname$ rname$
光标现在位于行中的最后一个“r”。在提示符下输入一些字符会覆盖最后一个“rname$”。最终结果是,如果前一个命令的输出不是以换行符结尾,我就看不到它是什么。这是最重要的修复问题。多余字符出现的方式,但可以覆盖,这并不困扰我,但如果能修复就更好了。
我已经尝试使用 bash 文档中的其他彩色提示,以及来自其他超级用户答案的有关彩色提示的一些彩色提示,它们的行为完全相同。
$ bash --version GNU bash,版本 3.1.17(1)-发布(x86_64-redhat-linux-gnu) 版权所有 (C) 2005 自由软件基金会,Inc.
不确定,但我认为是 CentOS,不知道是什么版本。给我一个检查操作系统的命令,我会运行它。
答案1
我首选的解决方案是让提示符始终以换行符开头。这样,我在最后一个命令输出之间总会有一个空行(当然,除了这种情况),这对我来说感觉更自然。最糟糕的情况是,我不会像您看到的那样覆盖文本,而是在中间没有空行。除非您尝试了一段时间并且无法忍受空行,否则我强烈推荐它。
PS1='\n\[\033[1;32m\]\u@\h\[\033[0m\]:\[\033[1;34m\]\w\[\033[0m\]\$ '
如果您愿意的话,还有一个额外的建议:我还使用多行提示符,使命令行在换行(或滚动,如果您的终端或 shell 配置为换行)之前尽可能长。我还想知道历史行号。这两个结合起来:
PS1='\n\[\033[1;32m\]\u@\h\[\033[0m\]:\[\033[1;34m\]\w\[\033[0m \!\]\n\$ '
最后,我还喜欢在运行命令之前和之后打印时间戳。我使用的简化版本是:
export PROMPT_COMMAND="date +\"%Y-%m-%d %H:%M:%S (%s)\"; trap 'date +\"%Y-%m-%d %H:%M:%S (%s)\"; trap DEBUG' DEBUG"
头晕了吗?:)
答案2
一个简单而优雅的解决方案是检查光标是否在第一列,如果不是,则发出换行符。我已经为另一个问题写了这个答案,你可以看看:https://serverfault.com/a/1131155/539096
以下是该答案的简要内容:
您可以使用以下命令检测光标位置:IFS=';' read -sdR -p $'\E[6n' ROW COL
。
变量COL
保存光标所在的当前列。如果$COL
不等于 1,则在设置 PS1 变量之前添加换行符。
这是我的实现:
_set_prompt() {
IFS=';' read -sdR -p $'\E[6n' ROW COL # Get cursor position
[ $COL -ne 1 ] && echo '' # Add newline if cursor is not at 1st column
PS1="........." # Your PS1 variable
}
PROMPT_COMMAND=${PROMPT_COMMAND:+$PROMPT_COMMAND; }'_set_prompt'
大多数现成的提示允许自定义,因此您可以轻松添加此检查。