Gilles a identifié votre problème principal, mais je voulais essayer de l'expliquer différemment.
Bash interprète l' invite spéciale s'échappe uniquement avant de développer les variables de l'invite. Cela signifie que l'utilisation \e
d'une variable développée à partir de l'invite ne fonctionne pas, même si elle fonctionne directement dans PS1
.
Par exemple, cela fonctionne comme prévu et donne du texte rouge:
PS1='\e[1;31m this is in red '
Mais ce n'est pas le cas, cela met simplement un littéral \e
dans l'invite:
RED='\e[1;31m'
PS1="$RED not in red "
Si vous souhaitez stocker les échappements de couleur dans des variables, vous pouvez utiliser ANSI-C quoting ( $'...'
) pour mettre un caractère d'échappement littéral dans la variable.
Pour ce faire, vous pouvez changer votre définition GREEN
, RED
et NONE
, de sorte que leur valeur est la séquence d'échappement réelle.
GREEN=$'\033[1;32m'
RED=$'\033[1;31m'
NONE=$'\033[m'
Si vous faites cela, votre premier PS1
avec les guillemets simples devrait fonctionner:
PS1='${RED}\h $(get_path) ${exitStatus}${NONE} '
Cependant, vous aurez alors un deuxième problème.
Essayez d'exécuter cela, puis appuyez sur Up Arrow, puis Home, et votre curseur ne reviendra pas au début de la ligne.
Pour résoudre ce problème, modifiez PS1
pour inclure \[
et \]
autour des séquences d'échappement de couleur, par exemple
PS1='\[${RED}\]\h $(get_path) $?\[${NONE}\] '
Vous ne pouvez pas l'utiliser get_exit_status
correctement ici, car sa sortie contient à la fois des caractères d'impression (le code de sortie) et des caractères non imprimables (les codes de couleur), et il n'y a aucun moyen de le marquer correctement dans l'invite. Le mettre \[...\]
le marquerait comme non imprimable en entier, ce qui n'est pas correct. Vous devrez modifier la fonction afin qu'elle n'imprime que le bon code couleur, puis l'entourer \[...\]
de l'invite.
\[
est\1
, et\[
est\2
. Celles-ci correspondent à quelqueRL_PROMPT_{START,END}_IGNORE
chose de readline qui lui demande d'ignorer les octets lors du comptage de la longueur de l'invite à l'écran. Voir lists.gnu.org/archive/html/bug-bash/2015-08/msg00027.html .\]
est\2
? Et voulez-vous dire que c'est pour cela qu'il est nécessaire${exitStatus}
? Mon point est que${exitStatus}
ne contient pas de caractères non-impression, si bash devrait être en mesure de déterminer correctement le nombre de caractères se déplace l'invite sans\[
et\]
dans\[${exitStatus}\]
.\e
et\033
(et\[
/\]
,,\u
et\h
) à partir de l'invite, il le fait juste avant d' étendre les variables. Fonctionne doncPS1='\e[1;31m red'
,red='\e[1;31m'; PS1='$red red'
non.Lorsque vous exécutez
PS1='${RED}\h $(get_path) ${exitStatus}${NONE} '
, laPS1
variable est définie sur${RED}\h $(get_path) ${exitStatus}${NONE}
, où\h
est uniquement une séquence d'échappement rapide. Une fois les séquences d'invites développées (cédant${RED}darkstar $(get_path) ${exitStatus}${NONE}
), le shell effectue les extensions habituelles telles que les extensions variables. Vous obtenez une invite affichée qui ressemble à\e[1;31mdarkstar PATH 0\e[m
. Rien en cours de route n'étend les\e
séquences en véritables personnages d'échappement.Lorsque vous exécutez
PS1="${RED}\h $(get_path) ${exitStatus}${NONE} "
, laPS1
variable est définie sur\e[1;31m\h PATH 0\e[m
. Les variablesRED
,exitStatus
etNONE
sont étendues au moment de la cession. Ensuite , l'invite contient trois séquences d'échappement rapides (\e
,\h
et\e
encore une fois). Il n'y a aucune variable shell à développer à ce stade.Pour voir les couleurs, vous avez besoin que les variables de couleur contiennent des caractères d'échappement réels. Vous pouvez le faire de cette façon:
$'…'
développe les séquences octales antislash et certaines séquences de lettres antislash telles que\n
, mais sans les inclure\e
. J'ai apporté trois autres modifications à votre invite:\[…\]
autour de séquences non imprimables telles que les commandes de changement de couleur. Sinon, votre affichage finira par se brouiller car bash ne peut pas déterminer la largeur de l'invite.\w
est une séquence d'échappement intégrée pour imprimer le répertoire courant.$?
dans l'invite si vous n'en avez pasPROMPT_COMMAND
en premier lieu.la source
PS1
est faux, mais les conseils d'utilisation$'...'
pourRED
etGREEN
ce devrait le faire fonctionner à l' aide dogbanePS1
.Essayer:
la source
Voici l'approche que j'ai choisie, elle évite l'utilisation de
PROMPT_COMMAND
.Alors mon
$PS1
est comme suit:la source
$?
peut avoir est un entier, vous devriez vraiment l'utiliser à laprintf '%b' "$GREEN"
place. Évitez également d'utiliser des noms de fonction préfixés par__
ou_
tels qu'ils sont utilisés par bash-complét.C'est parti - Cela fonctionne pour moi (TM) dans Ubuntu et d'autres Linux (Linuxen?).
La raison de la détection de code de sortie
$PS1
est qu'un hôte a un ensemble en lecture seule$PROMPT_COMMAND
avant la lecture de .bashrc.la source
Pour
PROMPT_COMMAND
, il est plus propre de définir une fonction et de l'utiliser:la source