Jak skonfigurować bash, aby wyświetlał status wyjścia dla każdego polecenia?

12

Każde polecenie uruchomione w bash zwraca kod wyjścia.

Ilekroć wpisuję polecenie w wierszu polecenia bash, chcę, aby wyświetlał status wyjścia, tj. echo $?

np. jeśli uruchomię echo "hello";po znaku zachęty bash, wynikiem powinno być:

linux@linux$ hello
linux@linux$ 0
ravidixit
źródło
Co powiesz na opublikowanie swojego pytania na unix.stackexchange.com ?
Dzięki @Frank. Ale czy to nie jest dobre miejsce do postawienia tego pytania?
ravidixit
Próbowałem wydrukować jako część zmiennej PS1, ale nie działa z powodów, których jeszcze nie rozumiem.
ravidixit

Odpowiedzi:

13

Kod wyjścia z ostatniego wykonanego polecenia jest przechowywany w $?zmiennej środowiskowej. Możesz więc po prostu dodać tę zmienną do domyślnego wiersza polecenia i zawsze będzie tam wydrukowany kod wyjścia. Pytanie jest przechowywane w $PS1zmiennej środowiskowej. Początkowo jest ustawiony w /etc/bash.bashrcskrypcie, a później w $HOME/.bashrc.

Tak więc edytuj wiersz $HOME/.bashrc( /etc/bash.bashrcbyłby obejmujący cały system) na podstawie jego wartości domyślnej:

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

do tego (na przykład):

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

Domyślny monit został zmieniony na:

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

0 w nawiasach to kod wyjścia, patrz:

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

Znaczenie znajduje się na stronie http://www.tldp.org/LDP/abs/html/exitcodes.html

chaos
źródło
Próbowałem to zrobić, ale dla tego podstępu nie działa. zawsze pokazuje [0] dla maszyny, nad którą pracuję.
ravidixit
Czy jesteś pewien, że wykonałeś bash? Czy możesz skopiować wynik readlink /proc/$$/exeproszę? 0 oznacza brak błędów, czy próbowałeś coś, co daje błąd: ^Calbo falsealbo asdasdasd?
chaos
1
@chaos Mam PS1 jako PS1=$(printf "%s\\\\u@\h:%s%s\w[$?]$%s " "$yellow" "$end" "$blue" "$end"), ale to pokazuje 0cały czas. Masz pomysł, dlaczego?
Maks.
1
Byłoby miło, gdyby status wyjścia był pokazywany tylko, jeśli jest nierówny 0
rubo77
1
@max To dlatego, że Twój $?jest już rozwinięty do 0ustawień PS1. Zrób, echo $PS1a zobaczysz. Musisz albo użyć pojedynczych cudzysłowów, albo uciec od tego \$?.
wisbucky,
7

Innym sposobem, który wybrałem z Arch Wiki, było użycie trap:

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

Efekt:

$ ( exit 1 )
code 1

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

$
muru
źródło
2
To nie do końca spełnia wymagania OP, ponieważ chce wydrukować status wyjścia, nawet jeśli wynosi zero - ale dokładnie tego szukałem.
Keith Thompson
2

Oto prosty przykład:

PS1='$? > '

Jeśli używasz podwójnych cudzysłowów, musisz dodać ukośnik odwrotny, aby uniknąć $:

PS1="\$? > "

Wynik:

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

Jeszcze lepszym sposobem jest wydrukowanie kodu wyjścia tylko wtedy, gdy jest on niezerowy.

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

Przykładowe dane wyjściowe:

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

Objaśnienie: ${var#pattern}to rozszerzenie parametru bash, które oznacza usunięcie najkrótszego pasującego wzorca z przodu $ var. W tym przypadku usuwamy 0z przodu $?, co skutecznie skraca kod wyjścia 0.

Jeśli użyjesz podwójnego cudzysłowu, $?zostanie zastąpiony, gdy PS1jest ustawiony, zamiast za każdym razem oceniany. Zrobić echo $PS1, aby potwierdzić, że nie ma sztywno wartość PS1.

wisbucky
źródło
Dziękuję od stycznia 2018 r. Chcę normalny monit z kodem wyjściowym na początku, jeśli jest niezerowy - to bardzo pomaga.
SDsolar