Pytanie powłoki Bash: gdzie jest $ RET?

0

Czytałem ten https://wiki.archlinux.org/index.php/Color_Bash_Prompt i skończyłem z następującymi:

# Stores the status of each command in $RET
PROMPT_COMMAND='RET=$?;'

# A colour.
RED_SHELL='\e[0;36m'

# Prints "Status 1" if RET is 1, for example.
RET_VISUALISE='$(if [[ $RET != 0 ]]; then echo -ne "Status \[$RED_SHELL\]$RET\n" && RET=0; fi;)'

# What to print for each prompt.
PS1="$RET_VISUALISE\[\e]0;\w\a\]\n\[\e[32m\]\u@\h \t \[\e[33m\]\w\[\e[0m\]\n\$ "

To robi prawie to, co chcę, z wyjątkiem sytuacji, gdy naciskam Enter, Enter, Enter wiele razy po poleceniu, które zwróciło status! = 0. W tym przypadku wypisuje „Status 1” za każdym razem, gdy naciskam Enter.

Właśnie tego && RET=0;część miała się pozbyć.

Nie rozumiem też, dlaczego env | grep RETwyświetla tylko PS1zawartość. Jaki jest zakres $RET?

Jewgienij Siergiejew
źródło

Odpowiedzi:

0

Przesłaniasz swoją za RET=0pomocą, RET=$?gdy drukowane jest następne pytanie bez wykonania polecenia pomiędzy nimi. $?zwraca ostatnią wykonaną komendę i tak jest nadal 1.

Bash pozwala na wychwytywanie błędów w wykonywanych poleceniach i wykonywanie kodu w odpowiedzi na to (raz):

function err_handle {
    RET=$?
    if [[ $RET != 0 ]]; then
        echo -ne "Status $RED_SHELL$RET\n"
    fi
}
trap 'err_handle' ERR
Daniel Beck
źródło
Racja, rozumiem! Wygląda więc na to, że $ RET istnieje tylko przez stosunkowo krótki czas, podczas gdy powłoka drukuje monit. Ale jak o tym myśleć? Czy dzieje się tak w przypadku niektórych funkcji, więc zakres $ RET jest lokalny dla tej funkcji?
Evgeni Sergeev
@EvgeniSergeev Przeczytaj ponownie pierwszy akapit. Możesz także uruchomić, set -xco umożliwia śledzenie. Gdy po prostu naciśniesz klawisz Enter (bez polecenia), ponownie RET=$?przypisuje kod powrotu ostatnio wykonanej funkcji , więc ustawienie zostanie po 0prostu zastąpione. W rzeczywistości, ponieważ ustawiono go w podpowłoce , przypisanie i tak nie jest propagowane z powrotem do zakresu zewnętrznego. Przykład: FOO=bar ; echo $FOO ; BAZ=$( FOO=baz ; echo $FOO ) ; echo $FOO ; echo $BAZ. Jak pisałem wcześniej, nie ma to znaczenia, ponieważ RET=$?po prostu ponownie przypisze ten sam (błąd) kod powrotu. Po prostu wypróbuj moje rozwiązanie i przejdź dalej.
Daniel Beck
Heh, przejdę dalej, kiedy nadejdzie właściwy czas. Co w tym przypadku może być niedługo, ponieważ to naprawdę wyjaśnia sprawy. To powłoki w tle rzeczą, która mnie mylić. Wygląda na to, że nie ma sposobu na umieszczanie poleceń w $ PS1 bez umieszczenia ich w podpowłoce. Świetne rozwiązanie!
Evgeni Sergeev,
@EvgeniSergeev Podczas gdy podpowłoka jest jej częścią, możesz łatwo przenieść dane wyjściowe do PROMPT_COMMAND- tylko po to, aby zostać ugryzionym RET=$?bez wykonywania innego polecenia podczas tworzenia następnego monitu. Więc nie, to nie tylko podpowłoka, ale przyczynia się.
Daniel Beck