我正在尝试配置 bash 以显示当前的 git 分支,基于例如这里,但我不知道如何让 bash 停止转义颜色字符串。我尝试的所有方法都会导致在提示行中输出颜色字符串。
我的提示如下:
valorin@gandalf:~/workspace/wyoa (\[\033[0;31m\]master\[\033[00m\])$
相关章节.bashrc
:
##
# Custom Git Branch name in prompt
##
function git_prompt {
if ! git rev-parse --git-dir > /dev/null 2>&1; then
return 0
fi
git_branch=$(git branch 2>/dev/null| sed -n '/^\*/s/^\* //p')
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
if git diff --quiet 2>/dev/null >&2; then
echo " (\[\033[0;31m\]$git_branch\[\033[00m\])"
else
echo " (\[\033[0;33m\]$git_branch\[\033[00m\])"
fi
else
if git diff --quiet 2>/dev/null >&2; then
echo " ($git_branch)"
else
echo "($git_branch*)"
fi
fi
}
if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]$(git_prompt)$ '
else
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w$(git_prompt)\$ '
fi
任何帮助,将不胜感激。
答案1
在 bash 提示符中,您不能拥有一个同时输出文本和颜色的函数。函数输出的所有内容都会被按字面意思理解。我建议用另一种方法来解决。
首先,提示符会尝试检查您是否在 git 树中,如果是,则向提示符添加一个彩色(分支)。您实际上只需要在更改目录时进行检查,而不是每次打印提示符时都进行检查,因此我们可以覆盖仅有的三个可以更改目录的命令,以将变量 git_branch 设置为当前分支的名称(如果有)。
cd() {
builtin cd "$@" || return
git_branch=$(git branch 2>/dev/null|sed -n '/^[*] /s///p') || true
}
pushd() {
builtin pushd "$@" || return
git_branch=$(git branch 2>/dev/null|sed -n '/^[*] /s///p') || true
}
popd() {
builtin popd "$@" || return
git_branch=$(git branch 2>/dev/null|sed -n '/^[*] /s///p') || true
}
接下来,检查 stderr 是否是终端,并使用 tput 设置颜色
user_color= dir_color= git_color= reset=
if [[ -t 2 ]]; then
user_color=$(tput setaf 2; tput bold)
dir_color=$(tput setaf 4; tput bold)
reset=$(tput sgr0)
fi
以及根据是否有变化输出两种颜色之一的函数
_git_color() {
[[ $git_branch && -t 2 ]] || return
if git diff --quiet >/dev/null 2>&1; then
tput setaf 1
else
tput setaf 3
fi
}
现在,把提示放在一起。这有点麻烦,因为有些变量应该在赋值时展开(现在),而有些变量应该在打印提示时展开,所以我们需要交替使用引号,而且它会变得相当长。为此使用数组应该有助于保持概览
prompt=(
"\[$user_color\]" '\u@\h' "\[$reset\]"
: "\[$dir_color\]" '\w' "\[$reset\]"
'${git_branch:+ (}'
'\[$(_git_color)\]' '$git_branch' "\[$reset\]"
'${git_branch:+)}'
'\$ '
)
我在这里省略了 debian_chroot 的内容,我自己从来不需要它,当然你可以根据需要添加它。最后,加入提示数组并清理我们不再需要的变量。
printf -v PS1 %s "${prompt[@]}"
unset user_color dir_color reset prompt