我的 .bashrc 中有这个:
LIGHTGREEN="\[\033[1;32m\]"
LIGHTRED="\[\033[1;31m\]"
WHITE="\[\033[0;37m\]"
RESET="\[\033[0;00m\]"
function error_test {
if [[ $? = "0" ]]; then
echo -e "$LIGHTGREEN"
else
echo -e "$LIGHTRED"
fi
}
PS1="\u\$(error_test)@\w$RESET \$ "
这似乎使 shell 输出准确:
username\[\]@~/
颜色代码周围的转义 [ 和 ] 显示在我的提示中。如果我从颜色周围删除转义码,它会起作用,但 bash 换行会惊人地失败。
注意如果这样做
PS1="LIGHTGREEN - whatever - $RESET"
它可以工作并且 [ 和 ] 不会被转义。但是,我想在函数内执行此操作,这似乎是问题所在。
我找不到任何关于此的好的文档。
man echo
甚至没有列出 -e 选项。 Bash 似乎有很多未记录的、传下来的知识。
我发现这个主题正在寻找如何通过从 bash 函数转义
\[ \]
来设置 bash 颜色的答案。
其实是有解决办法的。 Bash 允许在每次呈现提示时生成
PS1
提示。
set_bash_prompt(){
PS1="\u@\h $(call_your_function) $>"
}
PROMPT_COMMAND=set_bash_prompt
这样,每次显示提示时都会解释 PS1,因此它将调用函数并正确渲染所有转义序列,包括
\[ \]
,这对于计算提示长度很重要(例如,使命令历史记录正确工作)。
希望这会对某人有所帮助,因为我花了半天时间来解决这个问题。
使用
\001
代替 \[
,使用 \002
代替 \]
,并注意使用 PROMPT_COMMAND
的后果,因为该方法每次都会重置提示(这也可能正是您想要的) ).
bash 提示符在函数内回显颜色的解决方案解释为here:
\[
仅当您分配 PS1 时才特殊,如果您打印它们 在显示提示时运行的函数内部却没有 工作。在这种情况下,您需要使用字节\]
和\001
\002
还有这个其他答案指向相同的方向:
bash 特定的
和\[
实际上被翻译为\]
和\001
\002
按照接受的问题中的建议,在
PS1
调用的函数中设置 PROMPT_COMMAND
每次都会重置 PS1
,不允许其他脚本轻松修改您的 promtp(例如 Python virtualnenv activate.sh):
$ echo $PS1
<your PS1>
$ PS1="(TEST)$PS1"
$ echo $PS1
<(TEST) is not prepended to PS1 if you are using PROMPT_COMMAND as it is reset>
\[
和\]
必须直接在$PS*
中使用,而不是仅仅通过echo
输出。
LIGHTGREEN="\033[1;32m"
LIGHTRED="\033[1;31m"
WHITE="\033[0;37m"
RESET="\033[0;00m"
function error_test {
if [[ $? = "0" ]]; then
echo -e "$LIGHTGREEN"
else
echo -e "$LIGHTRED"
fi
}
PS1="\u\[\$(error_test)\]@\w\[$RESET\] \$ "
我意识到这是一个老话题,但我刚刚使用函数来解决这个问题。 诀窍是将函数的打印部分和非打印部分分开,以便您可以正确地将非打印部分用 [ ] 括起来。 通常我喜欢我的 ERROR.. 行是分开的(这不是问题),但如果所有内容都在一行中,这也可以正常工作。
注意我返回了之前的$?每个子 shell 的值是 $?从一个传播到下一个。
PS1="\n\
\[\`
cja_prv_retval=\$?;
if [ \$cja_prv_retval != 0 ];
then echo -ne \$E_ERROR;
fi
exit \$cja_prv_retval
\`\]\
\`
cja_prv_retval=\$?;
if [ \$cja_prv_retval != 0 ];
then echo -ne \"ERROR: RETURN CODE \$cja_prv_retval\";
fi
exit \$cja_prv_retval
\`\
\[\`
cja_prv_retval=\$?;
if [ \$cja_prv_retval != 0 ];
then echo -ne \$E_RESET;
fi
exit \$cja_prv_retval
\`\]\
${P_RESET}${P_GRAY}\! \t ${P_RED}\u${P_GRAY}@${P_GREEN}\h ${P_YELLOW}\w ${P_CYAN} ══>${P_RESET} "
这给了我一个
2021 12:28:05 cja@morpheus04 ~ ══>
如果没有错误,或者
ERROR: RETURN CODE 1 2021 12:28:16 cja@morpheus04 ~ ══>
如果有错误。 一切都正确间隔(多行历史编辑正常工作)。
这是我的
PS1
代码的彩色退出代码部分:
color_enabled() {
local -i colors=$(tput colors 2>/dev/null)
[[ $? -eq 0 ]] && [[ $colors -gt 2 ]]
}
BOLD_FORMAT="${BOLD_FORMAT-$(color_enabled && tput bold)}"
ERROR_FORMAT="${ERROR_FORMAT-$(color_enabled && tput setaf 1)}"
RESET_FORMAT="${RESET_FORMAT-$(color_enabled && tput sgr0)}"
# Exit code
PS1='$(exit_code=$?; [[ $exit_code -eq 0 ]] || printf %s $BOLD_FORMAT $ERROR_FORMAT $exit_code $RESET_FORMAT " ")'
屏幕截图(其中一个 Subversion 存储库路径已匿名):
这会很好用。
LIGHTGREEN="\e[32m"
LIGHTRED="\e[31m"
RESET="\e[0m"
error_test () {
if [[ $? = "0" ]]; then
echo -e "$LIGHTGREEN"
else
echo -e "$LIGHTRED"
fi
}
export PS1=$(printf "$(error_test) $(whoami)@${RESET}$(pwd) ")
另一个答案已经指出需要将
\[...\]
转换为 \001...\002
。要动态地执行此操作,您可以使用 Bash 的 @P
变量转换来“像提示一样”评估变量。这会评估颜色和粗体等的转义序列,例如 printf '%b'
和 echo -e
,但最重要的是,它还评估特定于提示的 \[...\]
构造。
对于问题中给出的函数,只需要一个小小的改变,将
echo -e "$foo"
更改为echo "${foo@P}"
(下面我使用printf '%s'
来明确避免echo的换行符)。
LIGHTGREEN="\[\033[1;32m\]"
LIGHTRED="\[\033[1;31m\]"
WHITE="\[\033[0;37m\]"
RESET="\[\033[0;00m\]"
function error_test {
if [[ $? = "0" ]]; then
printf '%s' "${LIGHTGREEN@P}"
else
printf '%s' "${LIGHTRED@P}"
fi
}
PS1="\u\$(error_test)@\w$RESET \$ "