Gilles zidentyfikował twój główny problem, ale chciałem spróbować wyjaśnić go inaczej.
Bash interpretuje specjalne znaki zachęty tylko przed rozwinięciem jakichkolwiek zmiennych w znaku zachęty. Oznacza to, że użycie \e
w zmiennej rozwiniętej z monitu nie działa, nawet jeśli działa bezpośrednio w PS1
.
Na przykład działa to zgodnie z oczekiwaniami i daje czerwony tekst:
PS1='\e[1;31m this is in red '
Ale tak nie jest, po prostu umieszcza literał \e
w znaku zachęty:
RED='\e[1;31m'
PS1="$RED not in red "
Jeśli chcesz przechowywać $'...'
znaki zmiany koloru w zmiennych, możesz użyć ANSI-C quoting ( ), aby wstawić dosłowny znak zmiany znaczenia w zmiennej.
Aby to zrobić, można zmienić definicję GREEN
, RED
i NONE
, więc ich wartość jest rzeczywista sekwencja ucieczki.
GREEN=$'\033[1;32m'
RED=$'\033[1;31m'
NONE=$'\033[m'
Jeśli to zrobisz, Twoje pierwsze PS1
z pojedynczymi cudzysłowami powinny działać:
PS1='${RED}\h $(get_path) ${exitStatus}${NONE} '
Będziesz miał jednak drugi problem.
Spróbuj uruchomić to, a następnie naciśnij Up Arrow, a następnie Home, a kursor nie wróci do początku linii.
Aby to naprawić, zmień, PS1
aby uwzględnić sekwencje specjalne koloru \[
i \]
wokół nich, np
PS1='\[${RED}\]\h $(get_path) $?\[${NONE}\] '
Nie można get_exit_status
tutaj prawidłowo używać , ponieważ jego dane wyjściowe zawierają zarówno znaki drukujące (kod wyjścia), jak i znaki niedrukowalne (kody kolorów) i nie ma możliwości prawidłowego oznaczenia go w monicie. Umieszczenie \[...\]
oznaczałoby go jako całkowicie niedrukowalny, co jest nieprawidłowe. Będziesz musiał zmienić funkcję, aby drukowała tylko odpowiedni kod koloru, a następnie otoczyła go \[...\]
w wierszu polecenia.
\[
jest\1
i\[
jest\2
. Te, które odpowiadają jakiejś linii readlineRL_PROMPT_{START,END}_IGNORE
, która prosi ją o zignorowanie bajtów podczas liczenia długości pytania na ekranie. Zobacz lists.gnu.org/archive/html/bug-bash/2015-08/msg00027.html .