Wydrukuj wartość zwracaną po wykonaniu programu

9

Zastanawiam się, jak ustawić opcję automatycznego drukowania wartości zwracanej po każdym uruchomieniu programu w terminalu bez pisania echo $?.

Czy to coś, co można skonfigurować? Codeblocks ma tę funkcję.

mr.backy
źródło

Odpowiedzi:

10

Tak, są dwa sposoby. Jednym z nich jest zestaw PROMPT_COMMAND, w .bashrc, drugi - aby określić podstawienia komend PS1dla echo $?polecenia.

Metoda 1:

Na stronie podręcznika bash:

PROMPT_COMMAND

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

Cokolwiek ustawisz dla tej zmiennej, będzie uruchamiane przed rysowaniem monitu za każdym razem. Próbny:

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

Zwróć uwagę na użycie \$?. Aby dokonać trwałej zmiany, zapisz ją.bashrc

Metoda 2

Załóżmy, że mój PS1monit jest ustawiony następująco:

PS1='
user@ubuntu:$> '

Jeśli chcę uruchomić jakiś program za każdym razem, gdy ten monit jest przerysowany na ekranie (czyli po każdym uruchomieniu poprzedniego polecenia), musiałbym go użyć command substitution $(. . .) i ustawić w wierszu polecenia w następujący sposób:

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

Próbny:

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

Zauważ, że podzieliłem PS1 na dwie linie: górna będzie mieć [ exitcode ]i dolna $> <blank space>'. Dlatego istnieje >zanim $> 'w drugiej linii (Wiodącym >jest PS2szybka dla multilinii poleceń). Możesz też zrobić coś takiego (zwróć uwagę na $'...'strukturę):

  $> PS1=$'[ $? ] \n$> '                                                                                                  
[ 0 ] 
$> 
Sergiy Kolodyazhnyy
źródło
+1 To faktycznie działa. Nie wątpię w reputację 27 tys. Osób, ale najwyraźniej podpowiedź nie jest „poleceniem”, więc używając $? w nie dostaje $? zresetować do zera, tak jak myślałem - nawet przy użyciu pierwszej metody, która wykonuje echo bez błędów.
Joe
PS1to tylko tekst drukowany przed wprowadzeniem przez użytkownika - nic więcej. To nie jest odporny na substytucji dopełniania parametrów i poleceń, więc można kłaść do $(...)na przykład $( pwd )i to tam pokazać. Użyłem tego z niestandardowym skryptem, aby pokazać moc baterii laptopa, na przykład
Sergiy Kolodyazhnyy
@mchid co masz na myśli?
Sergiy Kolodyazhnyy
1
@mchid „Przed wydaniem każdego głównego monitu”, a więc po zakończeniu wykonywania ostatniego polecenia.
Kos
1
@mchid jest uruchamiany przed wydrukowaniem monitu - więc zanim zaczniesz wpisywać następne polecenie.
muru
4

Metodą, którą wybrałem z Arch Wiki, jest trap ERR. trapjest używany w Bash do uruchamiania poleceń po odebraniu sygnału lub w przypadku niektórych innych zdarzeń. ERRPułapka jest ran, gdy obecne kończy wiersza poleceń z błędu - zwracana wartość nie jest 0. (Jeśli to nie zakończy się normalnie, wartość zwracana byłoby oczywiście 0.)

Na przykład:

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

Następnie:

$ echo foo
foo
$ false

code 1

$

(Uwaga: brak komunikatu po echopomyślnym uruchomieniu polecenia - co to znaczy, że wpisuję polecenie, a terminal nic nie robi? )

Wskazówka Arch Wiki poszła naprzód i pokolorowała wiadomość, aby uzyskać zauważalną żółtą wiadomość:

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

Efekt:

wprowadź opis zdjęcia tutaj

W rezultacie wszystko, co muszę zrobić, to uważać na żółty codesygnał wyjściowy, aby wiedzieć, że polecenie nie powiodło się.

muru
źródło