Soren
Soren

Reputation: 783

Include non-0 exit codes in the subsequent bash prompt

Occasionally, I will run a command that has a lot of output. Occasionally, the last 30-40 lines of that output (a.k.a. the only part of the output I ever really see) is fine, but much further up, there was an error. I'd like to make it easier to notice that the command failed. To do so, I want the return code to be part of my prompt. So I took my $PS1:

[\D{%Y-%m-%d} \t] \[\e]0;\u@\h: \w\a\]\$

...and extended it to this:

[\D{%Y-%m-%d} \t] ${?/^0$/} \[\e]0;\u@\h: \w\a\]\$

This results in a prompt like this:

[2011-05-10 09:38:07] 0 soren@lenny:~$ 

However, I'd like to find a way to have it only include the exit code if it was non-0. How can I do that? Sure, I could use

$(echo \$? | sed -e blah)

but as lightweight as sed is, it's still quite a bit more heavy weight than bash's builtin stuff.

Upvotes: 17

Views: 6987

Answers (9)

wisbucky
wisbucky

Reputation: 38033

Single quote example:

PS1='${?#0}> '

Double quote example (note the extra backslash to escape the $)

PS1="\${?#0}> "

Sample output:

> echo 'ok'
ok
> bogus
bogus: command not found
127> 

Explanation: ${var#pattern} is a bash parameter expansion that means remove the shortest matching pattern from the front of $var. So in this case, we are removing 0 from the front of $?, which would effectively truncate an exit code of 0.

If using double quotes, $? would be substituted when PS1 is set, instead of being evaluated each time. Do echo $PS1 to confirm you don't have a hardcoded value in PS1.

Upvotes: 1

peret
peret

Reputation: 11

This is the prompt I use, insert into .bashrc and source it to use it. As you can see the PREV_RET_VAL is being appended to PS1 only in the case the value is not 0.

COLOR_RED_BOLD="\[\e[31;1m\]"
COLOR_GREEN_BOLD="\[\e[32;1m\]"
COLOR_NONE="\[\e[0m\]"

# prompt function
promptFunc()
{
PREV_RET_VAL=$?;

PS1=""

PS1="${PS1}\e[1;30m[\e[1;34m\u@\H\e[1;30m:\e[0;37m \e[0;32m\d \T\e[1;30m]\e[1;37m \w\e[0;37m\[\033]0; \w - \u@\H \007\]\n\[\] "

if test $PREV_RET_VAL -eq 0
then
    PS1="${PS1}${COLOR_GREEN_BOLD}\\$ ${COLOR_NONE}"
else
    PS1="${PS1}${COLOR_RED_BOLD}\\$ [${PREV_RET_VAL}] ${COLOR_NONE}"
fi
}

PROMPT_COMMAND=promptFunc

Upvotes: 1

David Faure
David Faure

Reputation: 1997

For zsh users: insert this into your PROMPT: %(?,, -%?-)

Upvotes: 1

pwlars
pwlars

Reputation: 536

The following works for me:

PS1="[\D{%Y-%m-%d} \t] \u@\h:\w\a \${?##0} \$ "

example when $? is 0:

[2011-07-25 11:56:57] plars@plars-t500:~  $<br>
there is an extra space there ---------^^ not sure if that's a problem for you

example when $? is 130:

[2011-07-25 11:57:39] plars@plars-t500:~ 130 $

Upvotes: 9

Ben Jackson
Ben Jackson

Reputation: 93910

A common way to do this is to use trap ... ERR to execute arbitrary code when a command fails:

 $ trap 'echo $?' ERR
 $ true
 $ false
1
 $

A classic UNIX practical joke is trap 'echo You have new mail.' ERR

Upvotes: 4

dogbane
dogbane

Reputation: 274878

You can place an if-statement inside your PS1, which echoes out the exit status only if it is non-zero:

PS1='[\D{%Y-%m-%d} \t] $(es=$?; if [ $es -ne 0 ]; then echo $es; fi) \[\e]0;\u@\h: \w\a\]\$'

Upvotes: 4

&#252;berjesus
&#252;berjesus

Reputation: 834

You could use bash's built in pattern matching:

$ rc=0
$ echo ${rc##0}

$ rc=123
$ echo ${rc##0}
123

Upvotes: 6

l0b0
l0b0

Reputation: 58988

Here's what I use in my .bashrc to get a red number with the exit code. Verbose, but it gets the job done and should be portable.

highlight()
{
    if [ -x /usr/bin/tput ]
    then
        tput bold
        tput setaf $1
    fi
    shift
    printf -- "$@"
    if [ -x /usr/bin/tput ]
    then
        tput sgr0
    fi
}

highlight_error()
{
    highlight 1 "$@"
}

highlight_exit_code()
{
    exit_code=$?
    if [ $exit_code -ne 0 ]
    then
        highlight_error "$exit_code "
    fi
}

PS1='$(highlight_exit_code)...'

Upvotes: 4

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 799510

A little bit of printf abuse:

printf '%.*s' $? $?

Upvotes: 12

Related Questions