Imprimir valor de retorno após a execução do programa

9

Eu estou querendo saber como definir a opção para imprimir automaticamente o valor de retorno após cada execução do programa no terminal sem digitar echo $?.

É algo que pode ser configurado? Codeblocks tem esse recurso.

mr.backy
fonte

Respostas:

10

Sim, existem duas maneiras. Um deles é para conjunto PROMPT_COMMANDem .bashrc, o outro - a substituição de comando conjunto na PS1para o echo $?comando.

Método 1:

Na página do manual do bash:

PROMPT_COMMAND

      If set, the value is executed as a command prior to issuing each
      primary prompt.

O que quer que você defina essa variável, será executado antes de desenhar o prompt a cada vez. Demo:

$> PROMPT_COMMAND=" echo 'Last command exited with'  \$? 'code'  "
Last command exited with 0 code
$> ls /etc/passwd > /dev/null
Last command exited with 0 code
$> ls /etc/asdf > /dev/null
ls: cannot access /etc/asdf: No such file or directory
Last command exited with 2 code
$> 

Observe o uso de \$?. Para alteração permanente, salve-a em.bashrc

Método 2

Suponha que meu PS1prompt seja definido assim:

PS1='
user@ubuntu:$> '

Se eu quiser executar algum programa sempre que esse prompt for redesenhado na tela (que é após a execução de cada comando anterior), eu precisaria usá command substitution $(. . .) -lo e configurá-lo no prompt da seguinte maneira:

PS1=' [ $? ] 
user@ubuntu: $> '

Demo:

$> PS1=' [ $? ]
> $>_ '
 [ 0 ]
$>_ ls /etc/passwd > /dev/null
 [ 0 ]
$>_ ls /etc/asdf > /dev/null                                                                                                      
ls: cannot access /etc/asdf: No such file or directory
 [ 2 ]
$>_ 

Observe que eu divido meu PS1 em duas linhas, o topo terá [ exitcode ]e o fundo $> <blank space>'. É por isso que existe >antes $> 'na segunda linha (o principal >é o PS2prompt para comandos de várias linhas ). Como alternativa, você pode fazer algo assim (observe a $'...'estrutura):

  $> PS1=$'[ $? ] \n$> '                                                                                                  
[ 0 ] 
$> 
Sergiy Kolodyazhnyy
fonte
+1 Isso realmente funciona. Não estou duvidando de alguém com uma reputação de 27k, mas aparentemente o prompt não é um "comando", então usando $? nele não recebe $? redefina para zero como pensei que fosse - mesmo usando o primeiro método que executa o eco sem erros.
315 Joe Joe
PS1é apenas um texto que está sendo impresso antes de receber a entrada do usuário - nada além disso. Não é imune à expansão de parâmetros e substituições de comandos; portanto, você pode colocar qualquer coisa $(...), por exemplo, $( pwd )e isso seria mostrado lá. Eu usei isso com um script personalizado para mostrar a energia da bateria do laptop, por exemplo
Sergiy Kolodyazhnyy 2/16/16
@mchid o que você quer dizer?
Sergiy Kolodyazhnyy 8/0316
11
@mchid "Antes de emitir cada prompt primário", portanto, após a execução do último comando.
kos
11
O @mchid é executado antes da impressão do prompt - portanto, antes de você digitar o próximo comando.
muru 8/03/16
4

Um método que eu escolhi no Arch Wiki é o de trap ERR. trapé usado no Bash para executar comandos quando um sinal é recebido ou para certos outros eventos. Uma ERRinterceptação é executada sempre que a linha de comando atual termina com um erro - o valor de retorno não é 0. (Se foi encerrado normalmente, o valor de retorno seria obviamente 0.)

Então, por exemplo:

trap 'printf "\ncode %d\n\n" $?' ERR

Então:

$ echo foo
foo
$ false

code 1

$

(Nota: nenhuma mensagem após o echocomando ser executado com êxito - O que significa quando eu digito um comando e o terminal não faz nada? )

A dica do Arch Wiki foi adiante e coloriu a mensagem, para que você receba uma mensagem amarela perceptível:

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

Efeito:

insira a descrição da imagem aqui

Na verdade, tudo o que preciso fazer é ficar atento a um amarelo codena saída para saber que um comando falhou.

muru
fonte