l0b*_*0b0 5 bash prompt escape-characters
正如其他人所指出的,颜色代码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 "$@"
}
Run Code Online (Sandbox Code Playgroud)
最后一个函数用于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
Run Code Online (Sandbox Code Playgroud)
问题是转义的括号作为文字输出,所以我的提示在运行一个不存在的命令后看起来像这样:
\[\]\[\]127 \[\]user@machine:/path
$
Run Code Online (Sandbox Code Playgroud)
将逃生者包裹highlight_error起来printf %b并没有帮助。如何修复输出以便我可以将这些函数用于正常和转义命令替换?
似乎任何转义序列实际上都PS1需要包装在\[and\]中,但是如果您调用产生输出的函数或命令,则不需要包装它。
那么为什么不直接移动
"\$(exit_code=\${?#0}
highlight_error \"\${exit_code}\${exit_code:+ }\")"
Run Code Online (Sandbox Code Playgroud)
函数内部的东西,例如
print_error_if_error()
{
exit_code=$?
if [ $exit_code -ne 0 ]; then
highlight_error "$exit_code "
fi
}
Run Code Online (Sandbox Code Playgroud)
然后我想你可以删除所有的\[东西\]......
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
Run Code Online (Sandbox Code Playgroud)