web-dev-qa-db-fra.com

Utilisation de variables pour stocker les codes de couleur terminale pour PS1?

Dans mon .bashrc, J'utilise les codes de couleur terminale ANSI pour coloriser divers bits. Cela ressemble à ceci:

PS1='\u@\h:\w\[\033[33m\]$(virtual_env)\[\033[32m\]$(git_branch)\[\033[0m\]$ '

virtual_env et git_branch sont des fonctions de bash qui produisent des trucs sur stdout.

Maintenant, pour faciliter la lecture et la modification, je souhaite stocker les codes de couleur dans les variables et les voir, au lieu de les incorporer directement dans PS1. Donc, j'ai un tas de variables comme ceci:

GREEN="\[\033[32m\]"
YELLOW="\[\033[33m\]"
RESET="\[\033[0m\]"

J'aimerais pouvoir écrire quelque chose comme:

PS1='\u@\h:\w${YELLOW}$(virtual_env)${GREEN}$(git_branch)${RESET}$ '

Mais cela ne fonctionne pas - les codes de couleur apparaissent dans l'invite, comme ils sont échappés. Les couleurs fonctionnent correctement si j'utilise des guillemets doubles à la place pour PS1, mais l'invite ne change que lorsque je fais source ~/.bashrc.

J'ai essayé d'autres choses que j'ai vues les gens - en utilisant printf, en utilisant des guillemets simples pour les couleurs, mettez le \[ et \] dans PS1 Au lieu de la variable de couleur, mais rien ne semble fonctionner.

Comment utiliser des variables pour les codes de couleur?

33
Ismail Badawi

La solution consiste à obtenir la coquille de substituer les variables de couleur lors de la définition de l'invite, mais pas des fonctions. Pour ce faire, utilisez les citations doubles que vous aviez essayé à l'origine, mais échappez aux commandes afin qu'elles ne soient pas évaluées tant que l'invite n'est pas tirée.

PS1="\u@\h:\w${YELLOW}\$(virtual_env)${GREEN}\$(git_branch)${RESET}$ "

Notez le \ Avant le $() sur chaque commande.

Si on en reprend cela, nous voyons:

echo "$PS1"
\u@\h:\w\[\033[33m\]$(virtual_env)\[\033[32m\]$(git_branch)\[\033[0m\]$ 

Comme vous pouvez le constater, les variables de couleur ont été substituées, mais pas les commandes.

20
Patrick

Le problème est que votre variable GREEN contient la chaîne littérale consistant en "Backslash Backslash Backslash zéro trois trois" et ainsi de suite. Il ne contient pas par exemple an ASCII caractère d'échappement comme requis pour obtenir votre terminal pour changer de couleur.

Vous pouvez mettre des caractères de contrôle dans GREEN (et YELLOW et RESET) manuellement, mais une option bien meilleure est d'utiliser tput en premier lieu pour que Vous n'avez rien besoin du code difficile et vous prendrez en charge tout type de terminal.

GREEN="$(tput setaf 2)"
YELLOW="$(tput setaf 3)"
RESET="$(tput setaf 0)"

La raison pour laquelle c'est le monde lorsque vous mettez "Backslash zéro trois trois", etc ... directement dans PS1 Est-ce que cette interprétation de certaines séquences de barre oblique inverse est une fonctionnalité de l'invite de Bash (voir la section Invite dans le manuel. Cette substitution se produit avant Développement de paramètres, substitution de commande, expansion arithmétique et la suppression de la citation, cependant, cela n'est pas appliqué aux résultats de toutes les autres opérations.

7
Celada

Changez la façon dont vous remplissez $ vert, $ jaune et $ réinitialiser:

GREEN="$(echo -e "\033[32m")"
YELLOW="$(echo -e "\033[33m")"
RESET="$(echo -e "\033[0m")"

PS1='\u@\h:\w${YELLOW}$(virtual_env)${GREEN}$(git_branch)${RESET}$ '
2
Cyrus