bash提示和回显函数内部的颜色

时间:2011-07-06 05:48:46

标签: bash function colors echo

我的.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似乎有很多无证的手工知识。

6 个答案:

答案 0 :(得分:49)

我发现这个主题正在寻找答案如何通过从bash函数中转义\[ \]来设置bash颜色。

实际上有解决方案。 Bash允许在每次呈现提示时生成PS1提示。

set_bash_prompt(){
    PS1="\u@\h $(call_your_function) $>"
}

PROMPT_COMMAND=set_bash_prompt

这样,PS1将在每次显示提示时被解释,因此它将调用函数并正确呈现包括\[ \]在内的所有转义序列,这对于计算提示的长度很重要(例如,使命令历史正常工作) )。

希望这会帮助某人,因为我花了半天时间来解决这个问题。

答案 1 :(得分:23)

使用\001代替\[\002代替\],并注意使用PROMPT_COMMAND的后果,因为该方法会重置提示每一次(也可能就是你想要的)。

解释了bash提示回显函数内部颜色的解决方案here

  

\[ \]仅在您指定PS1时才会特殊,如果您打印它们   在显示提示时运行的函数内部,它不会   工作。在这种情况下,您需要使用字节\001\002

还有this other answer指向同一方向:

  

特定于bash的\[\]实际上已翻译为\001\002

PS1调用的函数内设置PROMPT_COMMAND,如同在接受的aswer中建议重置PS1每次都不允许其他脚本轻松修改你的promtp(例如Python virtualnenv {{ 3}}):

$ 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>

答案 2 :(得分:7)

\[\]必须直接在$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\] \$ "

答案 3 :(得分:0)

以下是my PS1 code的彩色退出代码部分:

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存储库路径): Color coded output

答案 4 :(得分:0)

我意识到这是一个古老的话题,但我只是使用了函数。诀窍是将功能的打印和非打印部分分开,以便您可以使用[]正确地包装非打印部件。通常我喜欢我的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 ~ ══>

如果有错误。一切都正确分开(多行历史编辑工作正常)。

答案 5 :(得分:0)

这样可以正常工作。

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) ")