Nous donnons ci-dessous des exemples pour les shells les plus
courants. Nous commençons avec zsh
car il offre des possibilités
qui facilitent grandement notre tâche. Nous progresserons ensuite vers des
exemples de plus en plus difficiles.
Dans tous les exemples ci-dessous, on teste la variable d'environnement TERM pour être certain de n'appliquer ces séquences que si l'on est dans un xterm (ou dérivé). Le test est fait sur TERM=xterm*, de manière à inclure au passage les variantes telles que TERM=xterm-color (défini par rxvt).
Encore une remarque au sujet des dérivés du C shell tels que tcsh
et csh
. Dans ces shells, les variables non-définies causent des
erreurs fatales. Il est dès lors nécessaire avant de tester la valeur de la
variable $TERM
, de tester si elle existe pour ne pas
interrompre un shell non-interactif. Pour y parvenir, il faut inclure les
exemples ci-dessous dans quelque chose du genre :
if ($?TERM) then
...
endif
(À notre avis, il s'agit d'une raison parmi beaucoup d'autres de ne
pas utiliser les C shells. Voir
Csh Programming Considered Harmful pour une
discussion utile).
Pour utiliser les exemples suivants, placez-les dans le fichier
d'initialisation du shell aproprié, c'est-à-dire un fichier lu lors du
lancement d'un shell interactif. Le plus souvent il s'agit de
.shellrc
(ex : .zshrc
, .tcshrc
, etc.)
On utilise quelques fonctions et codes offerts par zsh
:
precmd () fonction exécutée juste avant chaque invite
chpwd () fonction exécutée lors de chaque changement de répertoire
\e code du caractère escape (ESC)
\a code du caractère bip (BEL)
%n code remplacé par $USERNAME
%m code remplacé par le hostname jusqu'au premier '.'
%~ code remplacé par le répertoire, avec '~' à la place de $HOME
De nombreux autres codes sont disponibles, voir 'man zshmisc'.
Ainsi, le code suivant, mis dans ~/.zshrc, affiche "nom@serveur:répertoire" dans le titre de la fenêtre (et de l'icône).
case $TERM in
xterm*)
precmd () {print -Pn "\e]0;%n@%m: %~\a"}
;;
esac
On arrive au même résultat en utilisant chpwd()
au lieu de
precmd()
. La commande interne print
fonctionne comme
echo
, mais donne accès aux séquences %
.
tcsh
offre des possibilités similaires à celles de
zsh
:
precmd () fonction exécutée juste avant chaque invite
chpwd () fonction exécutée lors de chaque changement de répertoire
%n code remplacé par $USERNAME
%m code remplacé par le hostname jusqu'au premier '.'
%~ code remplacé par le répertoire, avec '~' à la place de $HOME
Malheureusement, il n'y a pas d'équivalent à la fonction print de
zsh
qui permette d'utiliser les codes de l'invite dans la chaîne
du titre ; le mieux que l'on puisse faire est d'utiliser les variables du
shell (dans ~/.tcshrc
) :
switch ($TERM)
case "xterm*":
alias precmd 'echo -n "\033]0;${HOST}:$cwd\007"'
breaksw
endsw
mais on obtient alors le chemin complet du répertoire, sans '~'. Par
contre, on peut mettre la chaîne dans l'invite :
switch ($TERM)
case "xterm*":
set prompt="%{\033]0;%n@%m:%~\007%}tcsh%# "
breaksw
default:
set prompt="tcsh%# "
breaksw
endsw
ce qui donne "tcsh%
" comme invite, et
"nom@serveur: répertoire
" dans
le titre (et l'icône) de xterm. Les "%{...%}"
doivent être placés autour des séquences d'échappement (et ne peuvent pas
être le dernier élément de l'invite, 'man tcsh' donne plus de détails).
bash
offre la variable PROMPT_COMMAND
qui contient une
commande à exécuter avant d'afficher l'invite. Ce code (inséré dans
~/.bashrc
) affiche nom@serveur: répertoire
dans le titre de la fenêtre (et de l'icône).
PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"'
où \033
est le caractère ESC
et \007
BEL
.
Il convient de noter que les guillemets jouent un rôle important : les
variables entre "..."
sont évaluées, alors que celles entre
"..."
ne le sont pas. Ainsi, PROMPT_COMMAND
reçoit bien le nom des variables, ces dernières étant évaluées lorsque
PROMPT_COMMAND
est invoquée.
Cependant, $PWD
donne le répertoire complet. Si l'on veut
utiliser le raccourci ~
, il faut placer toute la séquence
d'échappement dans l'invite pour avoir accès aux codes suivants :
\u est remplacé par $USERNAME
\h est remplacé par le hostname jusqu'au premier '.'
\w est remplacé par le repertoire, avec '~' à la place de $HOME
\[...\] signale une suite de caractère non-imprimables
Ainsi le code suivant produit l'invite bash$
, et place
nom@serveur: répertoire
dans le titre (et l'icône) de
xterm.
case $TERM in
xterm*)
PS1="\[\033]0;\u@\h: \w\007\]bash\$ "
;;
*)
PS1="bash\$ "
;;
esac
L'utilisation de \[...\]
signale à
bash
la présence de caractères non-imprimables, information dont
il a besoin lorsqu'il calcule la longueur de l'invite. Sans cette
précaution, les commandes d'édition de ligne ne savent plus très bien où
placer le curseur.
ksh
n'offre pas grand chose en terme de fonctions et codes, il
faut donc mettre notre chaîne dans l'invite pour qu'elle soit mise à jour
dynamiquement. L'exemple suivant produit l'invite ksh$
, et
place nom@serveur: répertoire
dans le titre (et l'icône) de
xterm.
case $TERM in
xterm*)
HOST=`hostname`
PS1='^[]0;${USER}@${HOST}: ${PWD}^Gksh$ '
;;
*)
PS1='ksh$ '
;;
esac
Cependant, $PWD
donne le répertoire complet. On peut ôter
le préfixe $HOME/
en utilisant la construction
${...##...}
. De même, on peut tronquer le
nom du serveur à l'aide de
${...%%...}
.
HOST=`hostname`
HOST=${HOST%%.*}
PS1='^[]0;${USER}@${HOST}: ${PWD##${HOME}/}^Gksh$ '
Les caractères ^[
et ^G
désignent
ESC
et BEL
(ils peuvent être saisis dans emacs à l'aide
de C-q ESC
et C-q C-g
).
C'est assez difficile à réaliser avec csh
. On finit par mettre ce
qui suit dans le ~/.cshrc :
switch ($TERM)
case "xterm*":
set host=`hostname`
alias cd 'cd \!*; echo -n "^[]0;${user}@${host}: ${cwd}^Gcsh% "'
breaksw
default:
set prompt='csh% '
breaksw
endsw
Il a fallu faire un alias de la commande cd
pour mettre à jour
l'invite. Les caractères ^[
et ^G
désignent ESC
et BEL
(ils peuvent être saisis dans emacs
à l'aide de C-q ESC
et C-q C-g
).
Notes : sur certains systèmes hostname -s
peut être utilisé
pour obtenir le nom de la machine au lieu du nom qualifié. Les utilisateurs
ayant des liens symboliques sur des répertoires trouveront `pwd`
plus précis que $cwd
.