将最后一个命令退出代码设置为 bash 提示符

Luk*_*uke 2 bash prompt bashrc

我正在运行 Ubuntu 18.04,我想设置我的 bash 提示,使其如下所示:

user:~/Documents [14:22:07] 1 $
Run Code Online (Sandbox Code Playgroud)

我的PS1如下:

ALERT_COLOR="$(tput setaf 1)"

# Display unsuccessful exit codes
function exit_status {
    last_status=$?
    if [[ $last_status != 0 ]]; then
        echo "$ALERT_COLOR[$last_status]"
    fi  
}

parse_git_branch() {
 git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}
if [ "$color_prompt" = yes ]; then
 PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u:\[\033[01;34m\]\w\[\033[01;31m\]$(parse_git_branch)\[\033[00m\] \[\033[36m\][\t] \[$ALERT_COLOR\]$exit_status \[\033[0;37m\]\$ '
else
 PS1='${debian_chroot:+($debian_chroot)}\u:\w$(parse_git_branch)\$ '
fi
unset color_prompt force_color_prompt
Run Code Online (Sandbox Code Playgroud)

除了退出代码之外,一切都有效。它从不显示退出代码,如果我只是$?在我的 PS1 中这样做,那么它总是显示为0

ilk*_*chu 7

问题在这里:

PS1='...\[$ALERT_COLOR\]$exit_status ...\$ '
                        ^^
Run Code Online (Sandbox Code Playgroud)

这是一个参数扩展,它不会调用您设置的函数。您需要在命令替换中调用该函数,例如$(exit_status), 或 from PROMPT_COMMAND。如果这样做,请注意\[ .. \]转义:Bash在提示中的其他扩展之前解释它们,因此您必须在提示字符串中对它们进行硬编码(它们不能是变量的一部分或在提示中展开的其他内容)。

如果不扩展从变量的提示转义对您来说似乎是倒退,我不能责怪您。但这就是它的记录方式

此外,下表描述了可在提示变量出现特殊字符PS1PS4[...] 的字符串被解码之后,它通过参数扩展,命令替换,膨胀[...]

这样的事情应该工作:

normal_color=$'\033[00m'
red_color=$'\033[41m'
exit_color=$normal_color

set_exit_color() {
    if [ "$?" != 0 ]; then
        exit_color=$red_color
    else
        exit_color=$normal_color
    fi
}

PROMPT_COMMAND=set_exit_color
PS1='\[$exit_color\][$?]\[$normal_color\] \w\$ '
Run Code Online (Sandbox Code Playgroud)

我原以为它需要一个临时变量来保存退出状态,但显然PROMPT_COMMAND不会修改$?在提示中展开的值。如果从提示字符串内部调用带有命令替换的函数,那么您需要一种解决方法,因为命令替换的退出代码生效。像这样的东西:

normal_color=$'\033[00m'
red_color=$'\033[41m'
exit_color=$normal_color

exit_color() {
    exit_code=$?
    if [ "$exit_code" != 0 ]; then
        echo "$red_color"
    else
        echo "$normal_color"
    fi
    return "$exit_code"
}

PS1='\[$(exit_color)\][$?]\[$normal_color\] \w\$ '
Run Code Online (Sandbox Code Playgroud)

我会使用带有PROMPT_COMMAND,的版本,只是为了保存由命令替换引起的子shell fork,但实际上效果很小。