Creating a Bash command line with red $ after the failure of the previous command

I am new to Bash programming and I am working on creating a Bash command line. My goal is to create an invitation that displays only the login name and hostname if they are different from what I usually use. I also want to add the current Git branch to the command line when it is in a directory under Git's control.

I would like to color the login section and node name section green, the blue path to the directory, the Git branch section is pink, and the delimiters (and $ icons) are white. However , when a previously executed command returns anything other than zero, I would like to color the $ red delimiter . The general format without colors is as follows:

loginname@hostname :~/current/path:branchname$ 

The only sections that are required are the directory path and the $ character. Here is the code I wrote for my .bashrc file :

 MYNAME="gwen" MYHOST="gwen-laptop" RED="\[\033[31m\]" WHITE="\[\033[0m\]" GREEN="\[\033[01;32m\]" BLUE="\[\033[01;34m\]" PINK="\[\033[01;35m\]" DOLLAR="if [ \$? = 0 ]; then echo ${WHITE}\$; else echo ${RED}\$${NORMAL}; fi" GITBRN='$(__git_ps1 "\033[0m:\033[01;35m%s")' USERNM="if [ \u != ${MYNAME} ]; then whoami; fi;" HOSTNM="if [ \h != ${MYHOST} ]; then echo -n @; hostname; fi;" COLONM="if [ \u != ${MYNAME} ] || [ \h != ${MYHOST} ]; then echo -n :; fi;" PS1="${GREEN}\`${USERNM}\`\`${HOSTNM}\`${WHITE}\`${COLONM}\`${BLUE}\w${GITBRN}\`${DOLLAR}\` " 

This code satisfies all my requirements, except that it always leaves a white $ character and does not color it at the corresponding time points . (I suspect that the problem is that "\ $?" In DOLLAR refers to a previously executed command, but DOLLAR is executed last when building PS1, so the previous execute statement is no longer the command that was run before PS1 started, it's something which was done to create the command line.) I am not sure how to solve this problem .

This code is ugly and needs to be reorganized . I tried to move all the color codes into my own variables, but when I used these color variables in the code for GITBRN, things went wrong, so instead I used literal colors instead.

I spent the whole day trying to get this code to work, and I think I won’t go anywhere now. Any suggestions on how to get this dollar sign painted red at the appropriate time would be most appreciated . I am also open to suggestions for refactoring code to make it more understandable and understandable.

PS I am a Ubuntu Linux user (Lucid Lynx).

+4
source share
3 answers

Use the PROMPT_COMMAND variable, which is executed before each main prompt according to the bash page.

For example (this still does not work, I'm trying to get it to work correctly, but I think it is possible):

 PROMPT_COMMAND="if [ \$? = 0 ]; then DOLLAR="${WHITE}\$${NORMAL}"; else DOLLAR="${RED}\$${NORMAL}"; fi" 

Edit: due to disappointment in executing commands and non-printable characters inside PS1 (sometimes \[ and \] are printed literally instead of being used as hints for PS1 ), I came up with this (replace ... with what you want in your invitation) :

 PROMPT_COMMAND='if [ $? = 0 ]; then DOLLAR_COLOR="\033[0m"; else DOLLAR_COLOR="\033[31m"; fi' PS1='...\[$(echo -ne $DOLLAR_COLOR)\]$\[\033[m\] ' 

Of course, using $() , you can put any parts of it that you like inside PS1 , instead of using PROMPT_COMMAND , I just like it, so PROMPT_COMMAND contains logic, and PS1 contains display commands.

+3
source

I got it for work:

 PROMPT_COMMAND='if [ $? = 0 ]; then PS1="\[\e[32;1m\]\ u@ \[\e[0m\e[30;47m\]\H\[\e[0m\]:\[\e[34;1m\]\w\[\e[0m\]$ "; else PS1="\[\e[31;1m\]\ u@ \[\e[0m\e[31;47m\]\H\[\e[0m\]:\[\e[31;1m\]\w\[\e[0m\]$ "; fi' 

enter image description here

Standing on the shelves @jtbandes. @jtbandes is the original author of the idea.

+2
source

Here Alexsandr’s answer is modified to display red only when the command fails, and not when you press enter on an empty command line, as Stefan requested.

 trap 'PREVIOUS_COMMAND=$THIS_COMMAND; THIS_COMMAND=$BASH_COMMAND' DEBUG read -r -d '' PROMPT_COMMAND << 'END' if [ $? = 0 -o $? == 130 -o "$PREVIOUS_COMMAND" = ": noop" ]; then PS1='\[\e[32;1m\]\ u@ \[\e[0m\e[30;47m\]\H\[\e[0m\]:\[\e[34;1m\]\w\[\e[0m\]$ ' else PS1='\[\e[31;1m\]\ u@ \[\e[0m\e[31;47m\]\H\[\e[0m\]:\[\e[31;1m\]\w\[\e[0m\]$ ' fi : noop END 
+1
source

Source: https://habr.com/ru/post/947748/


All Articles