作为其他的已经指出,颜色代码PS1
应该用 和 括起来\[
,\]
以避免它们占用水平空间。我已经添加了必要的代码.bashrc
:
highlight()
{
if [ -x /usr/bin/tput ]
then
printf '\['
tput bold
printf '\]'
printf '\['
tput setaf $1
printf '\]'
fi
shift
printf -- "$@"
if [ -x /usr/bin/tput ]
then
printf '\['
tput sgr0
printf '\]'
fi
}
highlight_error()
{
highlight 1 "$@"
}
最后一个函数用于PS1
正常和转义命令替换,以便能够根据上一个命令的结果更改字符串:
# Exit code
PS1="\$(exit_code=\${?#0}
highlight_error \"\${exit_code}\${exit_code:+ }\")"
...
if [ "$USER" == 'root' ]
then
PS1="${PS1}$(highlight_error '\u')"
else
PS1="${PS1}\u"
fi
问题是转义的括号作为文字输出,所以在运行不存在的命令后我的提示符看起来像这样:
\[\]\[\]127 \[\]user@machine:/path
$
将逃走的人包裹起来highlight_error
并printf %b
没有帮助。我怎样才能修复输出,以便我可以使用正常和转义命令替换的函数?
答案1
似乎任何转义序列实际上都PS1
需要包装在\[
and中\]
,但是如果您调用产生输出的函数或命令,则不需要包装它。
那么为什么不直接移动
"\$(exit_code=\${?#0}
highlight_error \"\${exit_code}\${exit_code:+ }\")"
函数内部的东西,例如
print_error_if_error()
{
exit_code=$?
if [ $exit_code -ne 0 ]; then
highlight_error "$exit_code "
fi
}
然后我想你可以删除所有的\[
东西\]
......
highlight()
{
if [ -x /usr/bin/tput ]
then
tput bold
tput setaf $1
fi
shift
printf -- "$@"
if [ -x /usr/bin/tput ]
then
tput sgr0
fi
}
highlight_error()
{
highlight 1 "$@"
}
PS1='$(print_error_if_error)'
# ...
if [ "$USER" = 'root' ]
then
PS1="${PS1}$(highlight_error '\u')"
else
PS1="${PS1}\u"
fi
答案2
看这个问题使用变量的解决方案$PROMPT_COMMAND
。在其中写入一个函数的名称,每次显示新提示之前都会调用该函数。如果您PS1
在该函数中进行设置,则可以解决您的问题并在函数中使用颜色命令:
# ... Using your highlight and highlight_error functions ...
prompt(){
exit_code=${?}
PS1="\u@\h \$ "
if [[ $exit_code != 0 ]];then
PS1="$(highlight_error "($exit_code)") $PS1"
fi
}
PROMPT_COMMAND="prompt"