Como configurar o bash para imprimir o status de saída de todos os comandos?

12

Todo comando executado no bash retorna com um código de saída.

Sempre que eu digitar um comando no prompt do bash, quero que ele mostre o status de saída, ou seja, echo $?

por exemplo, se eu executar echo "hello";no prompt do bash, a saída deve ser:

linux@linux$ hello
linux@linux$ 0
ravidixit
fonte
Que tal postar sua pergunta em unix.stackexchange.com ?
Obrigado @Frank. Mas também não é um bom lugar para fazer essa pergunta?
Ravidixit # 23/13
Tentei imprimi-lo como parte da variável PS1, mas não funciona por razões que ainda não entendi.
Ravidixit # 23/13

Respostas:

13

O código de saída do último comando executado é armazenado na $?variável de ambiente. Portanto, você pode adicionar essa variável ao prompt de comando padrão e sempre terá o código de saída impresso lá. O prompt é armazenado na $PS1variável de ambiente. Ele é inicialmente definido no /etc/bash.bashrcscript e posteriormente no $HOME/.bashrc.

Portanto, edite a linha $HOME/.bashrc( /etc/bash.bashrcseria para todo o sistema) a partir do valor padrão:

PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '

para isso (por exemplo):

PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w[$?] \$ '

Portanto, o prompt padrão foi alterado para:

user@host:/path/to/dir[0] $

O 0 entre colchetes é o seu código de saída, consulte:

user@host:~[0] $ ls
user@host:~[0] $ ls /root/
ls: cannot open directory /root/: Permission denied
user@host:~[2] $ ^C
user@host:~[130] $

Para os significados, consulte http://www.tldp.org/LDP/abs/html/exitcodes.html

caos
fonte
Eu tentei fazê-lo, mas para o bash na mão, não está funcionando. sempre mostra [0] para a máquina em que estou trabalhando.
Ravidixit
Tem certeza de que executa uma festança? Você pode copiar a saída de readlink /proc/$$/exepor favor? 0 significa que não há erro, você tentou algo que dê um erro: ^Cou falseou asdasdasd?
caos
1
@chaos Eu tenho o meu PS1 como PS1=$(printf "%s\\\\u@\h:%s%s\w[$?]$%s " "$yellow" "$end" "$blue" "$end"), mas ele mostra 0o tempo todo. Alguma idéia do porquê?
Max
1
Seria bom, se o estado de saída só seria mostrado, se é desigual 0
rubo77
1
@max É porque você $?já está expandido para 0quando definir o seu PS1. Faça echo $PS1e você verá. Você precisa usar aspas simples ou escapar como ele \$?.
22617 wisbucky
7

Outra maneira que eu escolhi no Arch Wiki foi usar trap:

EC() { echo -e '\e[1;33m'code $?'\e[m\n'; }
trap EC ERR

Efeito:

$ ( exit 1 )
code 1

$ some-non-existent-command
some-non-existent-command: command not found
code 127

$
muru
fonte
2
Isso não atende aos requisitos do OP, pois ele deseja imprimir o status de saída mesmo que seja zero - mas é exatamente o que eu estava procurando.
Keith Thompson
2

Aqui está um exemplo simples:

PS1='$? > '

Se você estiver usando aspas duplas, adicione uma barra invertida para escapar do $:

PS1="\$? > "

Resultado:

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

Uma maneira ainda melhor é imprimir apenas o código de saída quando for diferente de zero.

PS1='${?#0}> '    # single quote example
PS1="\${?#0}> "   # double quote example (requires extra backslash)

Saída de amostra:

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

Explicação: ${var#pattern}é uma expansão de parâmetro bash que significa remover o menor padrão de correspondência da frente de $ var. Portanto, neste caso, estamos removendo 0da frente do arquivo $?, o que truncaria efetivamente um código de saída de 0.

Se estiver usando aspas duplas, $?será substituído quando PS1estiver definido, em vez de ser avaliado todas as vezes. Faça echo $PS1para confirmar que você não tem um valor codificado em PS1.

wisbucky
fonte
Obrigado a partir de janeiro de 2018. Desejo o prompt normal com o código de saída no início, se for diferente de zero - isso ajuda muito.
SDsolar