Powerline : Un prompt de folie

powerline 29 août 2015

En lisant ma revue informatique préférée “Linux Pratique”, n°90 Juillet/Aout , je tombe sur un article qui me tape à l’œil concernant un plugin pour un terminal, il s’agit bien évidemment de Powerline.

Powerline est en réalité un utilitaire écrit en Python nous permettant de styliser de manière approfondie notre terminal (ZSH, Fish, BASH…), mais plus que ça, il nous permet d’afficher des informations extrêmement utile, lors de l’édition d’un projet Github par exemple.

Personnellement, j’utilise la source de Milkbikis qui est l’une des plus utilisée dans la communauté.

Le petit plus avec Powerline, c’est qu’il ne dépend d’aucun shell en particulier. En effet , beaucoup de scripts de personnalisation de prompts dépendent d’un shell en particulier (oh-my-fish/oh-my-zsh…), ce qui n’est pas le cas avec Powerline. Il peut être utilisé avec bashzsh ou bien encore fish (Je vous invite à aller voir le tutoriel d’Aerya pour installer fish si le cœur vous en dit).

Voilà le rendu avec zsh installé, ainsi que oh-my-zsh :

Interface Powerline de base

Dans cette capture d’écran, nous pouvons découper cette seule et unique ligne en différents éléments distincts, au total, nous en comptons 5, ces éléments sont nommés segments dans Powerline.

  • Le premier segment indique le nom de la machine (=hostname).
  • Le second segment nous indique le nom de notre nom d’utilisateur sous lequel nous sommes connectés.
  • Le troisième segment que nous pouvons voir est un cadenas, ce cadenas apparaît lorsque nous sommes connectés à distance en SSH, par exemple lors d’une session locale, il n’apparaîtra pas.
  • Le 4ème élément, représentant une vague, pour être précis un “tilde” signifie que nous sommes dans notre répertoire home.
  • Et enfin le dernier élément, le dernier élément affiche un # si nous sommes connectés en root, ou bien un % si nous sommes connectés sous un autre utilisateur. Comme ici je suis connecté en tant que barracudaxt, en toute logique, un est affiché.

Et enfin, après tous ces éléments, c’est là où nous allons écrire nos précieuses lignes de commandes.

Evidemment, tout ceci est personnalisable, nous pouvons par exemple déplacer différents éléments, pour inverser nom d’utilisateur et hostname, ou bien encore supprimer le cadenas si nous jugeons cet élément non-indispensable.

Voici une liste non-exhaustive des segments que nous fournit de base Powerline. Nous pouvons créer nos propres segments, le language de programation utilisé pour les segments est le python.

Désormais, voici le prompt que nous aurons par défaut avec Powerline en tant que root.

Powerline avec utilisateur root

Comme dans le screen précédent, nous avons une grande majorité de segments en commun avec un utilisateur lambda, cependant, nous pouvons noter quelques différences :

  • L’utilisateur root est cette fois-ci colorisé en rouge, et non plus en gris comme un utilisateur avec des droits lambda. Cette colorisation est là pour nous rappeler de faire attention à ce que nous faisons lorsque ous sommes connecter en root.
  • Après le “tilde“, nous pouvons apercevoir cette fois-ci un nom “WhatFreeGrabcela nous indique que je suis dans le sous répertoire WhatFreeGrab de mon répertoire home
  • Et enfin, comme expliquer précédemment, en dernier segment, nous pouvons voir un à la place du % étant donner que je suis connecté en root.

Chose importante à savoir, si le chemin est trop long, une partie du chemin est tronquée et est remplacée par  .

Chemin Tronqué

Comme nous pouvons le voir dans cet exemple, le chemin vers le dossier Classes  est en effet incomplet, une partie de celui-ci a été remplacé par … .

Nous n’avons toujours pas vu un point important, l’affichage d’informations pratiques lorsque nous travaillons dans un répertoire de travail Git.

Voici désormais la vue d’un projet.

Projet GitHub

Un élément en plus s’est rajouté, il s’agit du segment Git.

Ici, nous pouvons voir écrit master dans un fond vert, l’écriture master signifie que nous sommes dans la branche master du projet Github, la couleur verte signifie qu’aucun élément n’a été modifié dans le repository.

Repo Github file Edit

Toujours pareil, mais différence notable, cette fois-ci, master est écrit avec un fond rouge. Vous me direz “Et alors, c’est juste une couleur ?” Et bien NON, car en plus d’être un simple fond, ce changement de couleur nous indique qu’un fichier ou plus a été modifié, mais qu’en plus que celui-ci n’a pas été “commit” (Comprenez que les modifications n’ont pas été envoyées à la branche du repo)

Une fois que nous avons commit” notre fichier, voici l’état de notre shell :

Git Commited

Le prompt revient à son état initial, c’est à dire, la branche master écrit en vert, car nos fichiers ont été “commited”

J’ai pris l’exemple du gestionnaire Git, mais d’autres sont également disponibles, tel que svn ou bien fossil.

Powerline dispose de plusieurs thèmes de base, il est également possible de créer ses propres thèmes. Les thèmes de bases sont :

  • Basic
  • Default
  • Solarized-dark
  • washed

Personnellement, mon préféré est celui de base, c’est à dire default, cependant, voici une vue des différents autres thèmes :

  • Basic : 
  • Default : Default
  • Solarized-Dark : Solarized Dark
  • Washed : Washed

Comme vous pouvez le voir, les thèmes Basic et Washed semblent être adaptés à des terminaux avec fond clair Default pour les terminaux avec fond foncé, et enfin, Solarized-Dark avec…. aucun terminal. (Je trouve le thème plutôt piquant). Cependant, après réflexion, il se puisse que ce thème est été adapté pour les daltoniens.

Evidemment, il est possible de faire ses propres thèmes, pour cela, je vous invite à aller consulter un thème pour s’inspirer de celui-ci, par exemple, le thème par défaut

Après tous ces arguments ventant les mérites de Powerline, j’espère vous avoir donner l’envie de l’essayer, et comme on dit, l’essayer c’est l’adopter !

Cependant, si vous voulez vous essayez à Powerline, et à sa customisation quasi infinie, il faudra installer quelques pré-requis afin de le faire fonctionner correctement.

Tout d’abord, étant donner que Powerline est un programme Python, il nous faudra installer un environnement Python : apt-get install python2.7

Powerline utilisant python2, nous préférerons la version 2.7 à la 2.6, qui demande une dépendance supplémentaire.

Il nécessite également l’installation de polices supplémentaires, pour se faire, nous allons utiliser la source fonts de Powerline (CF Github)

Comme nous allons “cloner” une source Github, nous devons installer le paquage git-core afin de pouvoir manier cette source : apt-get install git-core

Nous sommes maintenant prêt à nous atteler à Powerline ainsi qu’à ses polices. Tout d’abord, nous allons commencer par installer ses polices

Attention, l’installation des polices devra être effectuée par chaque utilisateur désirant utiliser Powerline

On commence par cloner la source Github : git clone https://github.com/powerline/fonts puis nous nous rendons dans le dossier : cd fonts.

Une fois fait ceci, nous devons lancer le script d’installation afin d’installer les polices. Celui-ci s’occupera de copier toutes les polices dans notre répertoire personnel, et son sous-dossier .fonts (Si le dossier n’existe pas, le script le créera), pous les plus paranos d’entre nous, les sources du script sont disponibles ici

Répéter cette opération par chaque utilisateur souhaitant utiliser Powerline

Une fois fait ceci, nous pouvons supprimer le répertoire d’installation fontscd ../ && rm -R fonts/.

Pour les curieux, vous pouvez désormais vous apercevoir d’un dossier nommé .fonts  dans votre répertoire personnel contenant une multitude de fichiers ayant l’extension ttfotf ou encore pcf.gz

Une fois fonts d’installer, nous pouvons nous atteler à installer Powerline (qui est d’une simplicité enfantine).

Comme il s’agit d’une nouvelle fois d’une source Github, nous devons la copier en locale. Je vous conseille fortement de mettre le dossier powerline-shell dans un répertoire de votre variable $PATH (NDLR: La variable $PATH est une variable qui contient une multitude de dossiers. Notre shell va explorer ces dossiers pour y rechercher un exécutable, si rien n’a été trouvé, le shell nous retournera l’erreur “Command not found”).
Par exemple, voici le contenu de ma variable $PATH : /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Nous pouvons y apercevoir plusieurs chemins, séparés par des :, ce qui nous donne : /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Concrètement, cela signifie que nous pouvons placer notre répertoire dans le dossier cité au dessus que nous souhaitons, mais une fois de plus, je vous conseille un chemin standard, tel que /usr/bin.

Nous clonons donc notre powerline-shell dans /usr/bin/git clone https://github.com/milkbikis/powerline-shell.git /usr/bin/powerline-shell puis nous nous rendons dans le répertoire : cd /usr/bin/powerline-shell

Une fois dans ce dossier, vous allez apercevoir quelques fichiers et dossiers, actuellement, à notre stade actuel, un seul fichier est important : install.py, en effet, c’est grace à lui que nous allons pouvoir générer notre fichier exécutable powerline-shell.py qui va s’occuper de l’affichage de notre prompt.

Nous lançons donc notre installation : ./install.py. Le script va vous renvoyez en sortie ce message si tout se passe bien : “powerline-shell.py saved successfully”

Désormais, il va falloir “dire” à son prompt préféré d’utiliser Powerline.

Pour cela, nous devons ajouter quelques lignes à un fichier. Ce fichier dépend du shell que nous utilisons. Si vous ne savez pas le shell que vous utilisez, vous pouvez faire la commande echo $SHELL. Par exemple, voici la sortie de la commande me concernant : usr/bin/zsh, cela signifie que j’utilise zsh, ce qui est actuellement le cas.

Si vous utilisez zsh, vous devrez rajouter ces quelques lignes à la fin de votre fichier .zshrc se situant dans votre home. Une nouvelle fois, cette opération devra être répétée pour chaque utilisateur souhaitant utiliser Powerline

Voici le code à copier en fin de votre ~/.zshrc :

   export TERM='xterm-256color'
    function powerline_precmd() {
      PS1="$(/usr/bin/powerline-shell/powerline-shell.py $? --shell zsh 2> /dev/null)"
    }

    function install_powerline_precmd() {
      for s in "${precmd_functions[@]}"; do
        if [ "$s" = "powerline_precmd" ]; then
          return
        fi
      done
      precmd_functions+=(powerline_precmd)
    }

    if [ "$TERM" != "linux" ]; then
        install_powerline_precmd
    fi

Si vous disposez de fish, voici les lignes à copier dans ~/.config/fish/config.fish :

    function fish_prompt
        /usr/bin/powerline-shell/powerline-shell.py $status --shell bare ^/dev/null
    end

Et enfin, si vous diposez de cet ancêtre qu’est bash, voici les lignes à copier dans votre ~/.bashrc :

   export TERM='xterm-256color'
    function _update_ps1() {
       PS1="$(/usr/bin/powerline-shell/powerline-shell.py $? 2> /dev/null)"
    }

    if [ "$TERM" != "linux" ]; then
        PROMPT_COMMAND="_update_ps1; $PROMPT_COMMAND"
    fi

Et voilà, désormais, nous avons quasiment un prompt stylisé, dernière chose à faire, il faut désormais “resourcer” son fichier de configuration, pour cela, voici la commande à effectuer : source ~/$SHELL, remplacer $SHELL par le fichier de configuration que nous utilisons, pour moi par exemple, je devrais remplacer $SHELL par .zshrc (Attention à ne pas oublier le .).

Avoir un prompt stylisé, c’est bien beau, mais avoir un prompt qui correspond à nos besoins, c’est encore mieux. Malgré le fait que le prompt par défaut est plutôt sympa, il manque (pour moi) quelques segments tel que l’heure, ou bien encore la date, et vice-versa, certains sont en trop, comme la connexion SSH par exemple.

Pour cela, tout se fait dans un seul fichier : config.py

Voici le contenu de config.py de base, sans modification, en ayant enlever tous les commentaires inutiles :

SEGMENTS = [
'set_term_title',
'virtual_env',
'username',
'hostname',
'ssh',
'cwd',
'read_only',
'git',
'hg',
'svn',
'fossil',
'jobs',
# 'exit_code',
'root',
]
THEME = 'default'

C’est dans ce fichier que nous pouvons définir tous nos segments qui seront affichés sur notre prompt, nous retrouvons nos éléments que nous avons détaillés auparavant. Vous pouvez ajouter, ou bien supprimer des segments, voir même créer ses propres segments (Nous verrons plus tard comment créer un segment).

Attention, l’ordre des éléments est très important, par exemple, username est indiqué avant hostname, ce qui signifie concrêtement que nous allons voir afficher username puis hostname sur notre prompt. (Les 2 premiers éléments ne seront jamais afficher sur notre prompt, ne nous en occupons pas)

Par exemple, si je veux afficher la date (Attention, bien vérifier que le segment existe, celui-ci existe) avant le segment username, il me suffira d’écrire ‘date’, avant celui-ci. Faire très attention à la syntaxe, celle-ci est très importante, la syntaxe est bien nomdubloc‘, (Ne surtout pas oublier la virgule).

Désormais nous savons comment modifier sa configuration Powerline, il ne nous reste plus qu’à voir comment créer un segment.

Tout d’abord, première chose à savoir, tous les segments se situent dans un seul dossier : segments, qui se situe à la racine de notre dossier Powerline (Dans notre cas, le chemin vers segments sera /usr/bin/powerline-shell/segments/)

Si l’on se place dans ce dossier, et que nous exécutons la commande ls, nous apercevons tous les différents segments par défaut.

Dans notre exemple, nous allons créer un segment date qui va nous permettre d’afficher la date sur notre terminal (Comme je ne m’y connais pas en python, il s’agit du segment qui est donné par Linux Pratique).

Nous nous rendons dans le répertoire contenant les segments : cd /usr/bin/powerline-shell/segments/ puis créons le nouveau segment : date.py nano date.py.

Dedans, nous y copions ce code :

import subprocess

def add_date_segment():
try:
output = subprocess.check_output(['date','+%d/%m/%y'], stderr=subprocess.STDOUT)
output = output[:-1]
date = ' %s ' % output
powerline.append(date,Color.USERNAME_FG, Color.USERNAME_BG)

except OSError:
return
add_date_segment()

Nous pouvons découper ce bout de code en plusieurs parties : Importation des librairies (import subprocess), création de la fonction add_date_segment(), un bloc try/catch afin d’avoir une gestion des erreurs correctes, et enfin, notre code dans la partie try:

Les 3 premières lignes correspondent à du code Python standard, quand à la dernière ligne, celle-ci correspond a une commande spécifique.

powerline.append permet d’ajouter notre segment à notre prompt, celui-ci prend en compte 3 paramètres : date, c’est à dire le nom du segment, Color.USERNAME_FG, la couleur du texte, et enfin, Color.USERNAME_BG, la couleur d’arrière plan du segment.

Après avoir créé notre segment, et modifié notre fichier config.py, vous constaterez qu’aucun changement n’est visible, ceci est tout à fait normal. En effet, pour que la modification soit effective, il faut régénérer le fichier powerline-shell.py, de la même manière que la première fois : /usr/bin/powerline-shell/install.py.

Immédiatement après avoir re-créé ce fichier, notre prompt affichera désormais la date du jour.

Concernant les thèmes, il s’agit une nouvelle fois d’une classe python, affectant une valeur à une constante (Généralement, chaque constante définit une couleur).

Pour conclure, nous pouvons dire que Powerline est un prompt extrêmement puissant et customisable, pour n’importe qui souhaitant mettre un minimum les mains dans le cambouis.

Cependant, même si vous ne voulez pas mettre les mains dans le cambouis, il dispose d’une solide base qui nous permettra de le configurer simplement.

Combiné avec un petit zsh, ou encore fish selon vos goûts, ce duo vous accompagnera quotidiennement pour vos taches les plus courantes : maintenance de serveurs, mise à jour… Ou bien même pour un usage Desktop.

Toutefois, il faudra être extrêmement prudent à ne pas surcharger le prompt, et donc de ralentir la navigation. Cela se ressentira principalement via des connexions SSH, ou bien sur des machines de faible puissance.

Pour la rédaction de cet article, je me suis aidé du magazine “Linux Pratique”, de différents liens GitHub listés tout au long du tutoriel, ainsi que de différents tests personnels.

PS : Je viens de remarquer un problème caractères spéciaux lors de l’utilisation du client PuTTy, personnellement, je vous conseille d’utiliser XShell, non seulement car il gère les nouvelles polices, mais également car il s’agit d’un client extrêmement puissant, avec de large possibilités.

Mots clés