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 和颜色都能正常工作?
吉尔斯确定了您的主要问题,但我想尝试以不同的方式解释它。
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 引用 ( $'...') 在变量中放置文字转义字符。
要做到这一点,你可以改变你的定义GREEN,RED和NONE,因此他们的价值是实际的转义序列。
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 Arrow,Home您的光标将不会回到行的开头。
要解决这个问题,请更改PS1为包含\[和\]围绕颜色转义序列,例如
PS1='\[${RED}\]\h $(get_path) $?\[${NONE}\] '
Run Code Online (Sandbox Code Playgroud)
您不能get_exit_status在这里正确使用,因为它的输出包含打印(退出代码)和非打印字符(颜色代码),并且无法在提示中正确标记它。Putting\[...\]会将其完全标记为非打印,这是不正确的。您必须更改该函数,使其仅打印正确的颜色代码,然后\[...\]在提示中将其括起来。