Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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
up vote 4 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() {
    if ! $ran_something; then
preexec() {
show_non_zero_exit_status() {
    case $exit_status in
        echo $exit_status;;
PS1='$(show_non_zero_exit_status)$ '

But there's another similar problem: if you suspend a command, you'll get exit status 20 (zsh < 5.0.7) or 148 (bash and zsh >= 5.0.7).

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
        echo $exit_status;;

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

If you're using bash, add:

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


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.