Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I was reading this https://wiki.archlinux.org/index.php/Color_Bash_Prompt and ended up with the following:

# Stores the status of each command in $RET
PROMPT_COMMAND='RET=$?;'

# A colour.
RED_SHELL='\e[0;36m'

# Prints "Status 1" if RET is 1, for example.
RET_VISUALISE='$(if [[ $RET != 0 ]]; then echo -ne "Status \[$RED_SHELL\]$RET\n" && RET=0; fi;)'

# What to print for each prompt.
PS1="$RET_VISUALISE\[\e]0;\w\a\]\n\[\e[32m\]\u@\h \t \[\e[33m\]\w\[\e[0m\]\n\$ "

This does almost what I want, except when I press Enter,Enter,Enter multiple times after a command that returned status != 0. In this case it prints "Status 1" every time I press Enter.

This is what the && RET=0; part was supposed to get rid of.

Also, I don't understand why env | grep RET only shows the PS1 contents. What is the scope of $RET ?

share|improve this question

1 Answer 1

up vote 0 down vote accepted

You're overriding your RET=0 with RET=$? when the next prompt is printed without having executed a command in between. $? returns the last executed command's return value, and that's still 1.

Bash allows you to trap errors in executed commands and execute code in response to that (once):

function err_handle {
    RET=$?
    if [[ $RET != 0 ]]; then
        echo -ne "Status $RED_SHELL$RET\n"
    fi
}
trap 'err_handle' ERR
share|improve this answer
    
Right, I see! So the way it seems now is that $RET only exists for a relatively short amount of time, while the shell is printing the prompt. But how to think about this? Does this happen within some function, so that the scope of $RET is local to that function? –  Evgeni Sergeev Jun 24 '12 at 0:40
    
@EvgeniSergeev Read the first paragraph again. You could also run set -x which enables tracing. When you just press enter (no command), RET=$? assigns the return code of the last executed function again, so setting it to 0 just gets overridden. And in fact, since you set it within a subshell, the assignment isn't propagated back to the outside scope anyway. Example: FOO=bar ; echo $FOO ; BAZ=$( FOO=baz ; echo $FOO ) ; echo $FOO ; echo $BAZ. As I wrote before, it doesn't matter, since RET=$? will just assign the same (error) return code again. Just try my solution and move on. –  Daniel Beck Jun 24 '12 at 6:52
    
Heh, I'll move on when the time is right. Which, in this case, might be soon, because that really clarifies things. It's the subshell thing that confused me. It seems that there is no way to put commands into $PS1 without them being in a subshell. Great solution! –  Evgeni Sergeev Jun 25 '12 at 10:56
    
@EvgeniSergeev While the subshell is a part of it, you could easily move the output to PROMPT_COMMAND -- just to get bitten by RET=$? without executing another command when creating the next prompt. So, no, it's not just the subshell, but it contributes. –  Daniel Beck Jun 25 '12 at 17:23

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.