Bash:在提示中显示退出状态:

dog*_*ane 11 bash prompt

GREEN="\e[1;32m"
RED="\e[1;31m"
NONE="\e[m"

get_exit_status(){
   es=$?
   if [ $es -eq 0 ]
   then
       echo -e "${GREEN}${es}${NONE}"
   else
       echo -e "${RED}${es}${NONE}"
   fi
}

get_path(){
    #dummy function
    echo "PATH"
}

PROMPT_COMMAND='exitStatus=$(get_exit_status)'
Run Code Online (Sandbox Code Playgroud)

下面给出了正确的 exitStatus 但颜色变量没有扩展:

PS1='${RED}\h $(get_path) ${exitStatus}${NONE} '
Run Code Online (Sandbox Code Playgroud)

但是,下面的一个给了我颜色,但退出状态没有更新:

PS1="${RED}\h $(get_path) ${exitStatus}${NONE} "
Run Code Online (Sandbox Code Playgroud)

这样做的正确方法是什么?我该如何解决这个问题,以便 exitStatus 和颜色都能正常工作?

Mik*_*kel 8

吉尔斯确定了您的主要问题,但我想尝试以不同的方式解释它。

Bash仅扩展提示中的任何变量之前解释特殊提示转义。这意味着在从提示扩展的变量中使用不起作用,即使它直接在.\ePS1

例如,这按预期工作,并给出红色文本:

PS1='\e[1;31m this is in red '
Run Code Online (Sandbox Code Playgroud)

但这不是,它只是\e在提示中放入一个文字:

RED='\e[1;31m'
PS1="$RED not in red "
Run Code Online (Sandbox Code Playgroud)

如果要将颜色转义存储在变量中,可以使用 ANSI-C 引用 ( $'...') 在变量中放置文字转义字符。

要做到这一点,你可以改变你的定义GREENREDNONE,因此他们的价值是实际的转义序列。

GREEN=$'\033[1;32m'
RED=$'\033[1;31m'
NONE=$'\033[m'
Run Code Online (Sandbox Code Playgroud)

如果你这样做,你的第一个PS1单引号应该可以工作:

PS1='${RED}\h $(get_path) ${exitStatus}${NONE} '
Run Code Online (Sandbox Code Playgroud)

但是,那么您将遇到第二个问题。

尝试运行它,然后按 ,然后按Up ArrowHome您的光标将不会回到行的开头。

要解决这个问题,请更改PS1为包含\[\]围绕颜色转义序列,例如

PS1='\[${RED}\]\h $(get_path) $?\[${NONE}\] '
Run Code Online (Sandbox Code Playgroud)

您不能get_exit_status在这里正确使用,因为它的输出包含打印(退出代码)和非打印字符(颜色代码),并且无法在提示中正确标记它。Putting\[...\]会将其完全标记为非打印,这是不正确的。您必须更改该函数,使其仅打印正确的颜色代码,然后\[...\]在提示中将其括起来。