Configuration de bash sous Ubuntu

Par Ben Okopnik

[ À partir d'un fragment moisi d'anciennes écritures découvertes parmi les moutons de poussière dans une salle serveur abandonnée ]

Avec un peu de chance, cet article répondra à cette question, et vous dira peut-être comment faire.

La situation avant et maintenant

Au tout début, l'utilisation de Bash sous X était simple et prévisible : à la fin du démarrage système, le dernier runlevel, au choix :

Mais Ubuntu s'y est pris différemment : le runlevel passe le contrôle au gestionnaire de session GDM, qui lance votre gestionnaire de bureau (GNOME) et... c'est à peu près tout. Bien-sûr, c'est plus simple pour les nouveaux utilisateurs, mais vous perdez le contrôle du comportement du shell ; en fait, il n'y a plus de shell de connexion, ce qui signifie que les fichiers de configuration utilisateurs ne sont plus lus à la connexion. De même il n'y a plus de moyen standard pour lire une configuration spécifique au lancement de X. Que faire ?

Lorsque j'ai basculé sur Ubuntu, j'ai trouvé cette situation désagréable mais je l'ai gérée de différentes façons, essentiellement en bricolant en tant que root et en triturant la magie opaque de GDM, rien que je recommanderais à un nouvel utilisateur puisque c'est un excellent moyen pour ne plus pouvoir démarrer votre système. Récemment, je me suis décidé à regarder si je ne pouvais pas trouver une solution accessible à l'utilisateur moyen.

X à la trace

J'ai commencé par tracer l'exécution des scripts de démarrage de X dans /etc/X11 et /etc/gdm ; en gros, on commence par lire le fichier Xession qui paramètre les variables et charge les fichiers externes, puis le gestionnaire d'affichage défini dans /etc/X11/default-display-manager (gdm) prend la main. Ensuite GDM lance sa propre version de Xsession (/etc/gdm/Xsession) qui lit les scripts de /etc/X11/Xsession.d/ et rend la main, et ainsi de suite. En suivant ce processus, j'ai remarqué que /etc/gdm/Xsession lisait un fichier nommé "$HOME/.xprofile". Bingo, un fichier modifiable par l'utilisateur ! Mais il y avait un piège : le shebang de /etc/gdm/Xsession étant "#!/bin/sh", le .xprofile serait lu par sh, et non par bash, donc je devais éviter tout "bash-isme" (c'est à dire toute structure ou commande spécifique à bash, contrairement à celles exécutables par un simple Bourne shell). Au moins, bash hérite des variables définies par le bourne shell : il semble que certains enfants écoutent leur parents... Globalement, ça ne me semblait pas ajouter trop de difficulté, j'avais juste besoin de prendre quelques précautions supplémentaires. Précédemment, j'aurais simplement modifié le shebang de /etc/gdm/Xsession, mais j'étais déterminé à ne pas utiliser les privilèges du root, donc je m'interdisais cette option.

Le shell par défaut sous Ubuntu étant Bash, je savais qu'à chaque appel du shell, le fichier ~/.bashrc serait lu. Traditionnellement on met tout ce qui n'est lu qu'une fois, comme le PATH, les fonctions, "mesg n", etc. dans le fichier ~/.bash_profile et tout ce qui est lu à chaque lancement du shell dans ~/.bashrc, ce qui nous amène à le maintenir le plus court et le plus simple possible. Mais dans ce nouveau système, cet ordre des choses est modifié :

  1. j'ai décidé de laisser mon fichier ~/.bash_profile tel quel. Les bidouillages d'Ubuntu font qu'il n'est plus lu pour le moment mais ça ne veut pas dire que ce sera toujours le cas, et, si je change de nouveau de distribution, il sera à nouveau valide comme il l'a toujours été ;
  2. le fichier ~/.xprofile remplira désormais plus ou moins le rôle de ~/.bash_profile, excepté qu'il doit suivre la syntaxe du bourne shell. Cela signifie que, puisque sh ne gère pas l'"export -f", vous devrez donc exporter vos fonctions dans le ~/.bashrc. En outre, puisque tout est lu avant que la moindre console ne soit lancée, toute fonction relative aux consoles (par ex. "mesg") doit également être déplacée dans le .bashrc. J'ai de même fait attention à ne pas inclure les lignes de ~/.bash_profile qui font appel au ~/.bashrc : elles seraient lues à chaque fois que je lancerais un shell, mais ce n'est pas souhaitable quand X lit ~/.xprofile ;
  3. le ~/.bashrc sera désormais un peu plus lourd : on y définit désormais toutes les fonctions, donc il n'est plus nécessaire de les exporter puisque chaque shell les récupère à son lancement, de même que tout ce qui touche à la configuration de la console. La définition des alias, qui se trouvait déjà dans ce fichier, y reste.

En essence, en me basant sur les règles que je vient de définir, j'ai fini par combiner les deux fichiers ~/.bash_profile et ~/.bashrc et à éclater leur contenu dans ~/.xprofile et ~/.bashrc.

En détails

Sachez que vous serez sévèrement punis si vous faites une erreur : toute erreur dans ~/.xprofile fera planter votre session /etc/gdm/Xsession et aboutira à un message d'erreur de GDM - quelque chose du genre "Votre session n'a même pas duré 10 secondes. Le démarrage du serveur X (votre interface graphique) a échoué. Il est probable qu'il ne soit pas configuré correctement." Si jamais ça vous arrive, allez dans "Options / Choisir la session" dans GDM et choisissez "failsafe", puis jetez un œil au fichier ~/.xession_errors pour situer et corriger le problème, puis réessayez.

Voici des exemples un peu allégés de mes fichiers ~/.bash_profile, ~/.bashrc et ~/.profile. L'essentiel de ce que vous devez remarquer est ce qui a été déplacé, de quel fichier vers quel autre, et si ça a finalement trouvé sa place. J'ai surligné les lignes de ~/.xprofile en bleu et celles de ~/.bashrc en vert. Tout ce qui se trouve en noir et gras est perdu puisque ça n'est plus applicable.

~/.bash_profile

# ~/.bash_profile: execute au demarrage de bash

if [ -f ~/.bashrc ]; then
  . ~/.bashrc
fi

### EN VERT ###
eval $(lesspipe)
stty stop ''
mesg n
### FIN VERT ###

# Remarque : il faudrait re-adapter ces lignes a la syntaxe Bourne,
# puisque le shell Bourne n accepte pas l export et la declaration
# en une commande ; cependant le '/bin/sh' de Debian/Ubuntu l
# accepte, donc ce n est pas un probleme

### BLEU ###
export EDITOR=/usr/bin/vi
export ENV=~/.shrc
export LESSCHARSET=utf-8
export LIBGL_DRIVERS_PATH=/usr/lib/dri
export LYNX_CFG=${HOME}/.lynxrc
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/games:/usr/local/games:/var/svn/linuxgazette.net/bin
export PERLDOC="-otext"
export PI=`perl -we 'printf "%.48f\n", atan2(0,-1)'`
export RSYNC_RSH=/usr/bin/ssh
export SVN_SSH=/usr/bin/ssh
export WWW_HOME=file://${HOME}/lynx_bookmarks.html
export XTIDE_DEFAULT_LOCATION='St. Augustine, city dock, Florida'

# Sites
export LG="linuxgazette.net"
export NHC="www.nhc.noaa.gov"
export WWW="okopnik.com"
### FIN BLEU ###

TTY=`/usr/bin/tty 2>/dev/null`
[ ${TTY:5:3} == "tty" ] && {                 # If not a console, bail!
        color=(foo blue green magenta)       # tty's start at 1, arrays at 0...
        setterm -foreground ${color[${TTY#*y}]} -store
}

~/.xprofile

# ~/.xprofile: exécuté au demarrage de X, version modifiee de
# .bash_profile, doit etre executable par /bin/sh

export EDITOR=/usr/bin/vi
export LESSCHARSET=utf-8
export LIBGL_DRIVERS_PATH=/usr/lib/dri
export LYNX_CFG=${HOME}/.lynxrc
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/games:/usr/local/games:/var/svn/linuxgazette.net/bin
export PERLDOC="-otext"
export PI=`perl -we 'printf "%.48f\n", atan2(0,-1)'`
export RSYNC_RSH=/usr/bin/ssh
export SVN_SSH=/usr/bin/ssh
export WWW_HOME=file://${HOME}/lynx_bookmarks.html

# Sites
export LG="linuxgazette.net"
export NHC="www.nhc.noaa.gov"
export WWW="okopnik.com"

~/.bashrc

# ~/.bashrc: execute par bash(1) sauf pour les shells de login 
# vous trouverez des exemples dans /usr/share/doc/bash/examples/startup-files

# En cas de shell interactif :
if [ "$PS1" ]; then
        mesg n
        eval $(lesspipe)
        # Load aliases initially; part of the 'realias' hack
        source ~/.aliases
        # Set up the LG build vars
        source $HOME/.lgrc
        # Update LINES and COLUMNS
        shopt -s checkwinsize
        # Set the xterm title
        case $TERM in
                 gnome|nxterm|xterm*|rxvt*)
                                 PROMPT_COMMAND='echo -ne "\033]0;$USER@`hostname`: ${PWD}\007"' ;;
        esac
fi

####### Parametrages proxy ################
[ -f ~/ENABLE_PROXY ] && {
        export HTTP_PROXY=`cat ~/ENABLE_PROXY`
        export http_proxy=$HTTP_PROXY
        export FTP_PROXY=$HTTP_PROXY
        export ftp_proxy=$HTTP_PROXY
        export no_proxy=localhost
        export NO_PROXY=localhost

    # Automate w3m proxying
        export W3M_OPTIONS='-o use_proxy=1 -o http_proxy='$HTTP_PROXY' -o ftp_proxy='$FTP_PROXY' -o no_proxy=localhost'
        alias w3m="$W3M_OPTIONS "
}
####### Parametrages proxy ################

############ Fonctions #####################
calc() { perl -wle'print eval join "", @ARGV' $@; }
cdlg() { cd $LG_ARTICLES/`sed -n 's/currentIssue.*= *//;T;p' $LG_LIBPYTHON/lgconfig.py`; }
h() { history|grep "^ *[0-9]* *$1"; }
searchmail() { less -P "'n' to see the next match, 'q' to quit"  -p "$1" ~/Mail/Sent_mail; }
shake() { zless -p "$1" $HOME/Books/Other/The\ Complete\ Shakespeare.gz; }
ip() { ifconfig "${1:-eth0}"|sed -n '2s/.* inet addr:\([0-9.]*\) .*/\1/p'; }
pod() { cd /usr/share/perl/`perl -e'printf "%vd", $^V'`/pod; egrep "$1" *|less; }
export -f calc cdlg h searchmail shake ip pod
############ Functions #####################

Conclusion

Dans la pratique, le seul souci que j'avais - le fait que chaque invocation du shell soit un peu plus lente à cause du ~/.bashrc plus gros - ne s'est pas révélé comme étant un problème. J'ai fait un test avec " time bash -c exit " et le temps de chargement et fermeture supplémentaire est de 0,004 secondes. Pour l'instant, je considère ce problème comme résolu.

Adaptation française de la Gazette Linux

L'adaptation française de ce document a été réalisée dans le cadre du Projet de traduction de la Gazette Linux.

Vous pourrez lire d'autres articles traduits et en apprendre plus sur ce projet en visitant notre site : http://www.traduc.org/Gazette_Linux.

Si vous souhaitez apporter votre contribution, n'hésitez pas à nous rejoindre, nous serons heureux de vous accueillir.