bash 提示和函数内的回显颜色
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6592077/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
bash prompt and echoing colors inside a function
提问by Andy Ray
I have this in my .bashrc:
我的 .bashrc 中有这个:
LIGHTGREEN="\[3[1;32m\]"
LIGHTRED="\[3[1;31m\]"
WHITE="\[3[0;37m\]"
RESET="\[3[0;00m\]"
function error_test {
if [[ $? = "0" ]]; then
echo -e "$LIGHTGREEN"
else
echo -e "$LIGHTRED"
fi
}
PS1="\u$(error_test)@\w$RESET $ "
This seems to make the shell output exactly:
这似乎使 shell 输出完全正确:
username\[\]@~/
username\[\]@~/
The escaping [ and ] around the color codes are showing up in my prompt. If I remove the escape codes from around the colors it works, but then bash line wrapping fails stupendously.
颜色代码周围的转义 [ 和 ] 出现在我的提示中。如果我从它工作的颜色周围删除转义码,但是 bash 换行会惊人地失败。
Note if do PS1="LIGHTGREEN - whatever - $RESET"it works and the [ and ] are not escaped. However, I want to do this inside a function, which seems to be the issue.
请注意PS1="LIGHTGREEN - whatever - $RESET"它是否有效并且 [ 和 ] 没有被转义。但是,我想在一个函数中执行此操作,这似乎是问题所在。
I can't find any good documentation on this. man echodoesn't even list a -e option. Bash seems like it has a lot of undocumented, handmedown knowledge.
我找不到任何关于此的好的文档。man echo甚至没有列出 -e 选项。Bash 似乎有很多未记录的、手工制作的知识。
回答by thedk
I found this topic looking for answer how to set bash color with escaping \[ \]from bash function.
我发现这个主题正在寻找答案如何设置 bash 颜色并\[ \]从 bash 函数中转义。
Actually there is solution. Bash allows to generate PS1prompt each time prompt is rendered.
其实是有解决办法的。Bash 允许在PS1每次呈现提示时生成提示。
set_bash_prompt(){
PS1="\u@\h $(call_your_function) $>"
}
PROMPT_COMMAND=set_bash_prompt
This way, PS1 will be interpreted each time prompt will be displayed, so it will call function and render properly all escaping sequences including \[ \]which are important for counting length of prompt (e.g. to make command history work correctly).
这样,每次显示提示时都会解释 PS1,因此它将调用函数并正确呈现所有转义序列,包括\[ \]对计算提示长度很重要的序列(例如,使命令历史正常工作)。
Hopefully this will help someone, as I spend half a day to solve this issue.
希望这会对某人有所帮助,因为我花了半天时间来解决这个问题。
回答by MauricioRobayo
Use \001instead of \[and \002instead of \], and be aware of the consequences of usingPROMPT_COMMANDas that method will reset the prompt every single time (which can also be just what you want).
使用\001代替\[和\002代替\],并注意使用的后果,PROMPT_COMMAND因为该方法每次都会重置提示(这也可以是您想要的)。
The solution for bash prompt echoing colors inside a function is explained here:
这里解释了 bash 提示在函数内回显颜色的解决方案:
The
\[\]are only special when you assign PS1, if you print them inside a function that runs when the prompt is displayed it doesn't work. In this case you need to use the bytes\001and\002
在
\[\]当你将PS1,如果你把它们打印功能在运行提示在显示时不工作里面只有特殊。在这种情况下,您需要使用字节\001和\002
There is also this other answerthat points in the same direction:
bash-specific
\[and\]are in fact translated to\001and\002
庆典专用的
\[和\]其实都是翻译成\001和\002
Setting PS1inside a function called by PROMPT_COMMANDas suggested in the accepted aswer resets PS1every single time not allowing other scripts to easily modify your promtp (for example Python virtualnenv activate.sh):
按照接受的 aswer 中的建议在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>
回答by Ignacio Vazquez-Abrams
\[and \]must be used in $PS*directly, rather than just having them output via echo.
\[并且\]必须直接使用$PS*,而不仅仅是让它们通过echo.
LIGHTGREEN="3[1;32m"
LIGHTRED="3[1;31m"
WHITE="3[0;37m"
RESET="3[0;00m"
function error_test {
if [[ $? = "0" ]]; then
echo -e "$LIGHTGREEN"
else
echo -e "$LIGHTRED"
fi
}
PS1="\u\[$(error_test)\]@\w\[$RESET\] $ "
回答by l0b0
Here's the coloured exit code portion of my PS1code:
这是我的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 " ")'
Screenshot (with one Subversion repository path anonymized):

屏幕截图(有一个匿名的 Subversion 存储库路径):

回答by ChrisAshton84
I realize this is an old topic, but I just got this working with functions. The trick is to split the printing and non-printing parts of the function up so you can correctly bracket the non-printing parts with [ ]. Normally I like my ERROR.. line to be separate (and this isn't a problem then), but this also works correctly if everything is all in one line.
我意识到这是一个古老的话题,但我刚刚开始使用函数。诀窍是将函数的打印和非打印部分分开,这样您就可以用 [ ] 正确地将非打印部分括起来。通常我喜欢我的 ERROR.. 行是分开的(这不是问题),但如果一切都在一行中,这也能正常工作。
Note that I return the previous $? value from each sub-shell so $? gets propagated from one to the next.
请注意,我返回了之前的 $? 每个子壳的值所以 $? 从一个传播到另一个。
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} "
This gives me either
这给我要么
2021 12:28:05 cja@morpheus04 ~ ══>
if there is no error, or
如果没有错误,或者
ERROR: RETURN CODE 1 2021 12:28:16 cja@morpheus04 ~ ══>
if there is an error. Everything is correctly spaced (multi-line history editing works correctly).
如果有错误。一切都正确间隔(多行历史编辑工作正常)。
回答by Luis Lavaire
This will work fine.
这将正常工作。
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) ")

