Não defina $? para diferente de zero em Control+C

Não defina $? para diferente de zero em Control+C

My $PS1in Zsh inclui esta expressão: %(?. %?.) Significa «se o código de saída do comando anterior ( $?) for verdadeiro, mostre $?, senão não mostre nada». Isso geralmente é útil, mas uma coisa me incomoda: os shells definem o código de retorno do último comando como diferente de zero quando pressiono Control+C sem executar um comando! Zsh define como 1, Bash define como 130. Dash é o único shell em meu sistema que não o reinicia em Control+C.

Como reproduzir:

  1. Inicie o zsh ou bash.
  2. Pressione Control+C.
  3. echo $?.

Existe uma maneira de desativar esse comportamento no Zsh?

Responder1

Acho que não há como desligá-lo.

O primeiro pensamento é fazer com que o preexec defina uma variável que indique que um comando foi executado. Se você pressionasse Ctrl+C no prompt, ele não seria definido.

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)$ '

Mas há outro problema semelhante: se você suspender um comando, obterá o status de saída 20 (zsh < 5.0.7) ou 148 (bash e zsh >= 5.0.7).

Para contornar isso, você pode adicionar algo 20|148à caseafirmação acima, ou seja

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

Se você estiver usando zsh, certifique-se de ter setopt promptsubstem seu arquivo .zshrc.

Se você estiver usando o bash, adicione:

PROMPT_COMMAND=precmd
trap preexec DEBUG

mas na verdade você deveria usar a armadilha DEBUG mais complicada mencionada emhttps://superuser.com/a/175802/15334

Outra possibilidade é que setopt printexitvalueesteja próximo o suficiente do que você deseja.

Responder2

Espero que esta questão ainda interesse as pessoas em 2019...

130é um status de saída bastante raro (acredito que o UNIX implementado nos primeiros dias reconhece status de saída apenas até 128) - então ignore-o.

# pseudocode

if exit_status == 0 then
    do nothing
else
    if exit_status == 130 then
        do nothing
    else
        print " [red]exit_status[/red]"

Em zshtermos, isso se traduz em:

%(0?..%(130?.. %F{red}%?%f))

Atualizar:você escreveu que zshdefine o código de saída como 1on Ctrl-Ce bashto 130. Aqui, em 2019, ambos bashe zshvoltam 130.

informação relacionada