Configurer votre prompt BASH

Date: 20/02/2012 | Catégories: Open-source,Planet-libre,Systeme | Tags: ,,

S'il y a bien une chose que nous, geeks du monde libre, regardons en longueur de journée, c'est bien notre cher prompt (vous savez: $, # ...). C'est en lisant ce billet que je me suis dit que mon prompt actuel avait besoin d'un ravalement de façade:

Je souhaite mettre un peu de couleur dans mon nouveau prompt ainsi que des informations sur le dossier en cours. Quand ce dernier est un dossier de développement sous Git, je veux afficher la branche en cours d'utilisation et aussi savoir si mon répertoire est dans l'état "staging" (c'est à dire si je dois faire un commit).

Sans plus attendre, voici un aperçu de mon nouveau prompt (version 2 lignes):

Ce dernier se décompose en deux lignes:

  • user@host:folder (je garde cette structure pour simplifier les copier/coller en SSH, puis l'état Git (avec [le nom de la branche] en couleur rouge si staging, vert sinon)
  • le prompt proprement dit (là ou l'on va taper la commande :)) précédé de $ si on est un utilisateur standard et # si root

Pour la première ligne, j'utilise la variable BASH nommé PROMPT_COMMAND qui a le gros avantage d'être exécuté à chaque fois que le prompt est affiché (pas seulement à l'initialisation). La seconde ligne utilise la variable PS1.

Pour disposer de ce prompt, il est nécessaire d'insérer le code suivant à la fin de votre fichier .bashrc (il est aussi disponible sous GitHUB):

[cc lang="bash"]

# Colors

NoColor="33[0m"

Cyan="33[0;36m"

Green="33[0;32m"

Red="33[0;31m"

Yellow="33[0;33m"

# Chars

RootPrompt="#"

NonRootPrompt="$"

# Contextual prompt

prompt() {

USERNAME=`whoami`

HOSTNAME=`hostname`

CURRENTPATH=`pwd`

LEFTPROMPT=$Cyan$USERNAME@$HOSTNAME":"$Yellow$CURRENTPATH

let LEFTSIZE=$(echo -n "$USERNAME@$HOSTNAME:$CURRENTPATH" | wc -c)

RIGHTPROMPT=""

let RIGHTSIZE=0

GITSTATUS=$(git status 2> /dev/null)

#echo $GITSTATUS > /dev/null 2>&1

if [ $? -eq 0 ]; then

echo $GITSTATUS | grep "not staged" > /dev/null 2>&1

if [ $? -eq 0 ]; then

RIGHTPROMPT=$Red

else

RIGHTPROMPT=$Green

fi

BRANCH=`git describe --contains --all HEAD`

RIGHTPROMPT=$RIGHTPROMPT"[Git branch "$BRANCH"]"

let RIGHTSIZE=$(echo -n "[Git branch "$BRANCH"]" | wc -c)

fi

let BLANCKSIZE=${COLUMNS}-${LEFTSIZE}-${RIGHTSIZE}

RIGHTPROMPT=$RIGHTPROMPT$NoColor

echo -e -n $LEFTPROMPT

printf "%$(($BLANCKSIZE))s"

echo -e $RIGHTPROMPT

}

# Main prompt

PROMPT_COMMAND=prompt

if [ $EUID -ne 0 ]; then

PS1=$NonRootPrompt" "

else

PS1=$RootPrompt" "

fi

[/cc]

Update (20/02/2012): Je viens également d'ajouter une version allégée (en une seule ligne) de ce prompt. Le fichier de configuration BASH correspondant se trouve ici.

Update (21/02/2012): David Olivier vient de modifier  le script (version deux lignes) pour fonctionner avec SVN. A retrouver sur le GitHub.

Et vous, comment est votre prompt ?

 

  • http://blog.loicg.net Chibani

    Le fait “d’interroger” le statut git d’un dossier à chaque commande, ça ne ralentit pas ou ne sollicite pas trop la machine ?

    • http://blog.rolinh.ch/ Rolinh

      J’ai mis un système similaire dans la configuration de mon zsh et effectivement, si le dépôt est conséquent, cela peut prendre une ou deux secondes à charger au moment où je navigue dans le dossier du projet (mais plus par la suite)…

    • http://www.nicolargo.com NicoLargo

      Non, peut être un léger ralentissement lors de la première visite du répertoire.

      • http://blog.loicg.net Chibani

        Dans ce cas, je testerai à l’occasion.
        Merci pour l’astuce ;)

  • http://blog.rolinh.ch/ Rolinh

    Pour ma part, j’utilise zsh mais mon prompt est pas mal personnalisé (la couleur du path dans le prompt change en fonction des permissions, le user devient rouge si c’est root, la couleur de l’hôte change, affichage de l’état du dépôt pour Git et Mercurial).
    Bref, on peut trouver mon zshrc sur mon dépôt de config au cas où ça intéresse quelqu’un.
    Pour ce qui est de faire fonctionner les informations pour Mercurial et Git dans le prompt, j’en avais fait un post.

  • tkraosmini

    En effet, lorsque la taille du git est assez conséquent, il y a un ralentissement notable. Du coup, en me basant sur ton script j’ai utilisé __git_ps1 pour le nom de la branche courante et GIT_PS1_SHOWDIRTYSTATE pour l’état des fichiers (ces variables sont fournies par l’autocompletion de git). Cependant cela génère un souci au niveau de l’alignement à droite.

  • Capello

    Mon prompt ne comprant pas git.

    PS_DEBUT=”\[$ROUGE\]\u@\h\[$INIT\]“‘${READWRITERIGHT}’” \[$BLEU\]“‘${MYPWD:-”No myPwd defined”}’”\[$INIT\]”
    PS_FIN=”\[$BLEU\]\$\[$INIT\] ”
    PS1=$PS_DEBUT”\n”$PS_FIN

    La variable READWRITERIGHT contient mes droits dans le répertoire courant le W devient rouge si je ne peux pas écrire. De même pour le R.
    MYPWD contient le path courant modifié par un script, il contient des points d’atachements, ensuite, le chemin relatif au point d’atachement avec au minimum « n » répertoire, maximum « m » et nombre max de caractère autorisé.
    Ce qui donne :
    login@machine[RW] ~/…/ShareResources/SharedResource
    $

    Les variables ne sont mise à jour que lors des changements de répertoire. J’ai en effet créé une fonction cd() qui remplace celui du bash.

  • http://blog.chmd.fr chmd

    Vu le genre de choses que tu essaies de faire, tu sembles être une cible idéale pour zsh (d’autant plus que les propositions de complétion sont souvent de meilleure qualité sous zsh).

    Exemple avec ton prompt. Pour avoir (presque) la même chose, ça se fait en quelques lignes:

    autoload -U promptinit
    autoload -Uz vcs_info
    zstyle ‘:vcs_info:*’ stagedstr ‘%F{green}>%f’
    zstyle ‘:vcs_info:*’ unstagedstr ‘%F{yellow}<%f'
    zstyle ':vcs_info:*' check-for-changes true
    zstyle ':vcs_info:*' formats ' [%b%u%c]'
    zstyle ':vcs_info:*' actionformats ' [%b%u%c]'
    precmd () { vcs_info }
    setopt prompt_subst
    PROMPT='%n@%M:%~/ %# '
    RPROMPT='$vcs_info_msg_0_'

    Les différences principales:
    - ça marche pour presque tous les vcs (12 sont supportés, dont git, mercurial, bazaar, svn, cvs…)
    - la description offre un peu plus de granularité. L'état 'unstaged' (des fichiers versionnés ont été modifiés) est indiqué par une flèche jaune vers la gauche, tandis que l'état staged (des nouveaux fichiers ont été ajoutés) est indiqué par une flèche verte vers la droite.

  • Kevin

    Une bonne idée ce petit script que j’ai repris en l’adaptant légèrement… Toutefois, j’ai plusieurs soucis ici…

    De temps en temps au démarrage du terminal il ne m’affiche que ” $ ” pour le premier prompt… De la même façon lorsque je reviens sur une commande précédente ou que je me déplace dans la commande déjà saisie (en utilisant les flèches de direction), au bout d’un instant le prompte se change subitement en ” $ ” (avec de jolis soucis d’affichage à la clef…).

    • Kevin

      Je précise qu’il s’agit du script sur 1 ligne…
      Le soucis provient probablement du fait que bash ne connaisse pas la taille réelle de mon prompt…

      • http://www.nicolargo.com NicoLargo

        Je viens de mettre à jour le script. Tu peux voir si cela résout le problème ?

        • Kevin

          Bien joué !
          Merci.

  • Pingback: Configurer votre prompt BASH | LorfDotNet

  • Adadov

    Très bonne idée ce tuto, mais pour ma part j’utilise encore SVN au lieu de GIT …

    J’ai donc fait quelques adaptations et modifications comme par exemple ne pas éffacer le contenu de PROMPT_COMMAND si la variable contient déjà quelque chose, ou vérifier la présence d’un dossier .svn avant de lancer la moindre commande pour récupèrer des informations.

    Je serais très heureux de partager ma version du script si des gens sont intéressés.

  • JaShuGan

    Salut,

    Excellent tuto :).
    Je vais m’en inspirer.

  • Pingback: Nono’s Vrac 45 « m0le'o'blog

  • http://pierreclement.net Pierre

    Merci pour les astuces git et svn, j’ai svn dans la fonction prompt, histoire d’avoir les deux… Perso j’ai quelques variations de couleur, mais surtout pour mes serveur un affichage du type de serveur (dev ou prod).
    Voir mes bashrc ici (on pourrait faire un truc générique avec le dev/prod en fonction de l’hostname, mais ca impliquerait une intervention de l’utilisateur) : https://github.com/Pierrecle/Configs

  • http://salem.harrache.info SalemHarrache

    Sympa ça !
    Il y a un léger soucis lorsqu’on utilise un virtualenv, ça affiche pas le nom. Y moyen de de l’ajouter sans grande difficulté je pense, moi je n’y connais pas grand chose en bash…J’ai pris directement ce script : https://gist.github.com/1425703 si ça peut aider :)

  • http://www.hello-bokeh.com Anne-Sophie

    Sympatique, par contre, la commande “git describe –contains –all HEAD” ne renvoie pas exactement la branche sur laquelle on travaille mais plutôt la dernière sur laquelle on vient de commiter si je ne m’abuse.

    • http://www.nicolargo.com nicolargo

      Tout à fait exact !

      Je viens de commiter une nouvelle version avec:
      BRANCH=`git rev-parse –abbrev-ref HEAD`

      • http://www.hello-bokeh.com Anne-Sophie

        Merci ! (J’avais essayé de bricoler un truc avec git branch et grep mais ce n’était pas très satisfaisant… )

  • Pingback: Prompt Bash pour GIT – ®om's blog