Gilles ha identificato il tuo problema principale, ma volevo provare a spiegarlo diversamente.
Bash interpreta il escape speciale del prompt solo prima di espandere qualsiasi variabile nel prompt. Ciò significa che l'utilizzo \e
in una variabile che viene espansa dal prompt non funziona, anche se funziona direttamente in PS1
.
Ad esempio, funziona come previsto e fornisce un testo rosso:
PS1='\e[1;31m this is in red '
Ma non è così, mette semplicemente un messaggio \e
nel prompt:
RED='\e[1;31m'
PS1="$RED not in red "
Se si desidera memorizzare le fughe di colore in variabili, è possibile utilizzare le virgolette ANSI-C ( $'...'
) per inserire un carattere di escape letterale nella variabile.
Per fare questo, è possibile cambiare la definizione di GREEN
, RED
e NONE
, quindi il loro valore è la sequenza di escape vero e proprio.
GREEN=$'\033[1;32m'
RED=$'\033[1;31m'
NONE=$'\033[m'
Se lo fai, il tuo primo PS1
con le virgolette singole dovrebbe funzionare:
PS1='${RED}\h $(get_path) ${exitStatus}${NONE} '
Tuttavia, avrai un secondo problema.
Prova a eseguirlo, quindi premi Up Arrow, quindi Homeil cursore non tornerà all'inizio della riga.
Per risolvere questo problema, cambia PS1
per includere \[
e \]
attorno alle sequenze di escape del colore, ad es
PS1='\[${RED}\]\h $(get_path) $?\[${NONE}\] '
Non è possibile utilizzare get_exit_status
correttamente qui, poiché il suo output contiene sia caratteri di stampa (il codice di uscita) sia caratteri non stampabili (i codici di colore), e non c'è modo di contrassegnarlo correttamente nel prompt. Mettere \[...\]
lo contrassegnerebbe come non stampabile per intero, il che non è corretto. Dovrai modificare la funzione in modo che stampi solo il codice colore corretto, quindi racchiudilo \[...\]
nel prompt.
\[
è\1
ed\[
è\2
. Quelli da corrispondono a qualcosa di readlineRL_PROMPT_{START,END}_IGNORE
che gli chiede di ignorare i byte quando si conteggia la lunghezza del prompt sullo schermo. Vedi lists.gnu.org/archive/html/bug-bash/2015-08/msg00027.html .