bash prompt and echoing colors inside a function

后端 未结 6 1887
感情败类
感情败类 2020-12-24 00:50

I have this in my .bashrc:

LIGHTGREEN=\"\\[\\033[1;32m\\]\"
LIGHTRED=\"\\[\\033[1;31m\\]\"
WHITE=\"\\[\\033[0;37m\\]\"
RESET=\"\\[\\033[0;00m\\]\"

function          


        
相关标签:
6条回答
  • 2020-12-24 01:15

    \[ and \] must be used in $PS* directly, rather than just having them output via 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\] \$ "
    
    0 讨论(0)
  • 2020-12-24 01:19

    I found this topic looking for answer how to set bash color with escaping \[ \] from bash function.

    Actually there is solution. Bash allows to generate PS1 prompt each time prompt is rendered.

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

    Hopefully this will help someone, as I spend half a day to solve this issue.

    0 讨论(0)
  • 2020-12-24 01:22

    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.

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

    0 讨论(0)
  • 2020-12-24 01:24

    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) ")
    
    0 讨论(0)
  • 2020-12-24 01:26

    Use \001 instead of \[ and \002 instead of \], and be aware of the consequences of usingPROMPT_COMMAND as that method will reset the prompt every single time (which can also be just what you want).

    The solution for bash prompt echoing colors inside a function is explained here:

    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 \001 and \002

    There is also this other answer that points in the same direction:

    bash-specific \[ and \] are in fact translated to \001 and \002

    Setting PS1 inside a function called by PROMPT_COMMAND as suggested in the accepted aswer resets PS1 every single time not allowing other scripts to easily modify your promtp (for example 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>
    
    0 讨论(0)
  • 2020-12-24 01:41

    Here's the coloured exit code portion of 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 " ")'
    

    Screenshot (with one Subversion repository path anonymized): Color coded output

    0 讨论(0)
提交回复
热议问题