Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

My $PS1 in Zsh includes this expression: %(?. %?.) It means «if exit code of previous command ($?) is true, show $?, else show nothing». This is generally useful, but one thing annoys me: shells set return code of last command to non-zero when I press Control+C without running a command! Zsh sets it to 1, Bash sets it to 130. Dash is the only shell on my system that does not reset it on Control+C.

How to reproduce:

  1. Launch zsh or bash.
  2. Press Control+C.
  3. echo $?.

Is there a way to turn off this behavior on Zsh?

share|improve this question

1 Answer 1

up vote 5 down vote accepted

I don't think there's any way to turn it off.

First thought is to have preexec set a variable that indicates a command was run. If you pressed Ctrl+C at the prompt, it wouldn't get set.

precmd() {
    exit_status=$?
    if ! $ran_something; then
        exit_status=0
    fi
    ran_something=false
}
preexec() {
    ran_something=true
}
show_non_zero_exit_status() {
    case $exit_status in
    0)
        :;;
    *)
        echo $exit_status;;
    esac
}
PS1='$(show_non_zero_exit_status)$ '

But there's another similar problem: if you suspend a command, you'll get exit status 20 in zsh, and 148 in bash.

To get around that, you can add 20|148 to the case statement above, i.e.

show_non_zero_exit_status() {
    case $exit_status in
    0|20|148)
        :;;
    *)
        echo $exit_status;;
    esac
}

If you're using zsh, make sure you have setopt promptsubst in your .zshrc.

If you're using bash, add:

PROMPT_COMMAND=precmd
trap preexec DEBUG

but really you should use the more complicated DEBUG trap mentioned in http://superuser.com/a/175802/15334

Another possibility is that setopt printexitvalue is close enough to what you want.

share|improve this answer
    
Thank you! setopt printexitvalue seems to do what I want (make non-zero exit code immediately visible), and does not require prompt_subst, which I try my best to keep off). It would be better if its output wasn't identical to one after a background job has quit though, but it's not a big deal. Thanks again. –  Mischa Arefiev Oct 12 '13 at 20:40

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.