Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash prompt with the last exit code

Tags:

linux

bash

prompt

I've been trying to customize my Bash prompt so that it will look like

[feralin@localhost ~]$ _ 

with colors. I managed to get constant colors (the same colors every time I see the prompt), but I want the username ('feralin') to appear red, instead of green, if the last command had a nonzero exit status. I came up with:

\e[1;33m[$(if [[ $? == 0  ]]; then echo "\e[0;31m"; else echo "\e[0;32m"; fi)\u\e[m@\e[1;34m\h \e[0;35m\W\e[1;33m]$ \e[m 

However, from my observations, the $(if ...; fi) seems to be evaluated once, when the .bashrc is run, and the result is substituted forever after. This makes the name always green, even if the last exit code is nonzero (as in, echo $?). Is this what is happening? Or is it simply something else wrong with my prompt? Long question short, how do I get my prompt to use the last exit code?

like image 399
feralin Avatar asked May 23 '13 13:05

feralin


People also ask

How do you get the last code out of exit command?

Extracting the elusive exit code To display the exit code for the last command you ran on the command line, use the following command: $ echo $? The displayed response contains no pomp or circumstance. It's simply a number.

How do I find my last command bash return code?

To check the exit code we can simply print the $? special variable in bash. This variable will print the exit code of the last run command.

How do I check script exit code?

Checking Bash Exit Code Launch a terminal, and run any command. Check the value of the shell variable “$?” for the exit code. $ echo $? As the “date” command ran successfully, the exit code is 0.

What is the exit code of a bash script?

For the bash shell's purposes, a command which exits with a zero (0) exit status has succeeded. A non-zero (1-255) exit status indicates failure. If a command is not found, the child process created to execute it returns a status of 127.


2 Answers

If you don't want to use the prompt command there are two things you need to take into account:

  1. getting the value of $? before anything else. Otherwise it'll be overridden.
  2. escaping all the $'s in the PS1 (so it's not evaluated when you assign it)

Working example using a variable

PS1="\$(VALU="\$?" ; echo \$VALU ; date ; if [ \$VALU == 0 ]; then echo zero; else echo nonzero; fi) " 

Working example without a variable

Here the if needs to be the first thing, before any command that would override the $?.

PS1="\$(if [ \$? == 0 ]; then echo zero; else echo nonzero; fi) " 

Notice how the \$() is escaped so it's not executed right away, but each time PS1 is used. Also all the uses of \$?.

like image 29
helios Avatar answered Oct 13 '22 19:10

helios


As you are starting to border on a complex PS1, you might consider using PROMPT_COMMAND. With this, you set it to a function, and it will be run after each command to generate the prompt.

You could try the following in your ~/.bashrc file:

PROMPT_COMMAND=__prompt_command    # Function to generate PS1 after CMDs  __prompt_command() {     local EXIT="$?"                # This needs to be first     PS1=""      local RCol='\[\e[0m\]'      local Red='\[\e[0;31m\]'     local Gre='\[\e[0;32m\]'     local BYel='\[\e[1;33m\]'     local BBlu='\[\e[1;34m\]'     local Pur='\[\e[0;35m\]'      if [ $EXIT != 0 ]; then         PS1+="${Red}\u${RCol}"        # Add red if exit code non 0     else         PS1+="${Gre}\u${RCol}"     fi      PS1+="${RCol}@${BBlu}\h ${Pur}\W${BYel}$ ${RCol}" } 

This should do what it sounds like you want. Take a look a my bashrc's sub file if you want to see all the things I do with my __prompt_command function.

like image 113
demure Avatar answered Oct 13 '22 19:10

demure