如何阻止 bash 提示颜色消失

如何阻止 bash 提示颜色消失

我正在尝试配置 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

相关内容