Copyright © 2000 Pat Eyler
Copyright © 2000 Pierre Tane
Article paru dans le n°53 de la Gazette Linux de mai 2000.
Cet article est publié selon les termes de la Open Publication License. La Linux Gazette n'est ni produite, ni sponsorisée, ni avalisée par notre hébergeur principal, SSC, Inc.
Table des matières
De nombreux tutoriels et introductions à bash parlent de l'utilisation des alias. Malheureusement, la plupart d'entre eux ne traitent pas les fonctions. C'est vraiment dommage car les fonctions offrent de mutiples avantages que n'ont pas les alias.
Les alias sont de simples substitutions de chaînes. Le shell prend le premier mot d'une commande et le compare à la liste courante des alias. Par ailleurs, si le dernier caractère d'un alias est un espace, il regarde aussi le mot suivant. Par exemple :
$
alias 1='echo '$
alias 2='ceci est un alias'$
1 2 ceci est un alias$
Les alias ne proposent pas le support d'instructions de branchements, d'arguments sur la ligne de commande ou tous les autres trucs qui rendent la ligne de commande si utile. Par ailleurs, les règles gérant l'expansion des alias sont un peu délicates, suffisamment pour que la page de man de bash bash(1) recommande : placez toujours les définitions d'alias sur des lignes isolées, et n'utilisez jamais la commande alias dans les commandes composées.
Les fonctions sont en fait des scripts qui tournent dans le contexte courant du shell. (Ce court moment de jargon technique veut dire qu'en l'occurrence, un second shell n'est pas démarré pour faire tourner la fonction , celle-ci est executée par le shell courant). Les fonctions sont des scripts dans le plein sens du terme et possèdent donc la flexibilité et la puissance de ces derniers.
Vous pouvez créer des fonctions de différentes manières. Vous pouvez tout simplement la stocker dans un fichier et exécuter le contenu avec la commande . (sur la ligne de commande ou dans un script de démarrage). Vous pouvez également entrer la fonction sur la ligne de commande. Une fonction n'est ainsi disponible que dans la session dans laquelle elle a été définie par l'une des deux méthodes ci-dessus (ou alors dans une session héritée d'un shell parent).
Pour créer une fonction sur la ligne de commande, il vous faut faire comme suit :
$
gla() {
> ls -la | grep $1
> }
C'est une fonction plutôt simple qui pourrait également être implantée sous la forme d'un alias. (Les raisons pour lesquelles il ne vaut mieux pas le faire via un alias seront exposées plus tard). Écrite comme précédemment, elle affiche une version plus détaillée du contenu du répertoire courant et recherche toutes les occurences du premier argument. Vous pourriez la rendre plus intéressante en utilisant awk pour trouver les fichiers qui dépassent 1024 octets. Cela donnerait :
$
gla() {
> ls -la | grep $1 | awk ' { if ( $5 > 1024 ) print $0 } '
> }
Vous ne pourriez pas faire cela avec un alias car il ne suffit plus de
remplacer gla
par ls -la | grep. Comme elle est écrite sous forme
de fonction, cela ne pose pas de problème d'utiliser $1
(pour se référer
au premier argument de gla
) n'importe où dans le corps de vos commandes.
Pour un exemple un peu plus conséquent (d'accord, bien plus conséquent),
supposez que vous travaillez sur deux projets avec deux dépôts CVS
différents. Vous voudrez certainement écrire une fonction qui donne les bonnes
valeurs aux variables CVSROOT
et CVS_RSH
ou encore qui efface ces
valeurs si un argument indéterminé est donné en argument. Il serait également
intéressant que la commande cvs update soit lancée si vous donnez
l'argument update
à votre fonction. Avec des alias, vous pouvez le faire
mais seulement en lançant de mutiples alias sur la ligne de commande. En
utilisant des fonctions, vous pouvez créer un fichier texte (appelé par exemple
setcvs.sh
) contenant ce qui suit :
setcvs() { export done="no" if [ "$1" = "unset" ] # nous voulons effacer toutes les variables then echo -n "Vidage des variables en relation avec CVS: " export CVSROOT="" export CVS_RSH="" export done="yes" echo "Terminé" fi if ( pwd | grep projects/reporting > /dev/null && \ [ "$done" != "yes" ] ) # si nous sommes dans l'espace reporting et que cela n'a pas déjà # été fait then echo -n "Mise en place de cvs pour le projet reporting: " export CVSROOT="issdata:/usr/local/cvs/" export CVS_RSH="ssh" export done="yes" echo "Terminé" fi if ( pwd | grep projects/nightly > /dev/null && \ [ "$done" != "yes" ] ) # si nous sommes dans l'espace nightly et que cela n'a pas déjà # été fait then echo -n "Mise en place de cvs pour le projet nightly: " export CVSROOT="/home/cvs/" export done="yes" echo "Terminé" fi if [ "$1" = "update" ] # Nous voulons mettre à jour l arborescence courante vis à vis du # serveur cvs après avoir initialisé les bonnes variables then if [ -z "$CVSROOT" ] # si $CVSROOT est de longueur nulle (elle a été vidée ou n'a # jamais été initialisée), lancer une erreur et ne rien faire then echo "variables cvs non intialisées ... vérifiez le répertoire dans lequel vous vous trouvez et réessayez" elif [ -n "$CVSROOT" ] # si $CVSROOT est définie, essayer de faire la MAJ then echo "MAJ de l'arborescence locale" cvs -q update echo "Terminé" fi fi }
Vous pouvez alors enregistrer la fonction et l'utiliser de la manière suivante :
$
. ~/scripts/setcvs$
cd$
pwd /home/a257455$
setcvs unset Vidage des variables en relation avec CVS: Terminé$
echo $CVSROOT$
echo $CVS_RSH$
cd projects/reporting/htdocs/$
setcvs Mise en place de cvs pour le projet project: Terminé$
echo $CVSROOT issdata:/usr/local/cvs/$
echo $CVS_RSH ssh$
cd ../../nightly/$
setcvs Mise en place de cvs pour le projet nightly: Terminé$
setcvs update Mise en place de cvs pour le projet nightly: Terminé MAJ de l'arborescence locale Terminé$
cd$
setcvs unset Vidage des variables en relation avec CVS: Terminé$
setcvs update variables cvs non intialisées ... vérifiez le répertoire dans lequel vous vous trouvez et réessayez$
Les fonctions peuvent faire bien plus que les alias : la fonction ci-dessus
montre l'utilisation de branchements simples, du contrôle d'erreur et des
variables. Bien sûr, elle pourrait être améliorée mais elle montre quand même
quelques points importants. Un autre aspect est que les fonctions peuvent être
réutilisées dans des scripts alors que ce n'est pas le cas pour les alias. Par
exemple, compte tenu du fait que la fonction ci-dessus est stockée dans un
fichier appelé ~/scripts/setcvs
, vous pouvez écrire un script comme
celui-ci :
#!/bin/bash # un script d'exemple # d'abord, charger les fonctions . ~/scripts/setcvs # aller dans les répertoires de projet et les mettre à jour via CVS cd ~/projects/reporting/htdocs setcvs update cd - cd ~/projects/nightly setcvs update # retourner d'où l'on vient et vider les variables CVS cd - setcvs unset
Les alias sont de petites choses bien pratiques mais j'espère qu'après cette introduction, vous allez trouver les fonctions au moins aussi intéressantes (et peut-être même plus utiles). Cependant un défaut commun aux alias et aux fonctions tient dans le fait que vous ne devriez pas remplacer une commande standard par un alias ou une fonction. Il est trop facile de causer des dommages en essayant d'exécuter votre alias alors qu'il n'est pas défini. Imaginez la différence entre :
$
alias rm='rm -i'$
cd ~/scratch$
rm * # ici l'alias à rm vous protège et vous efface de manière # interactive le contenu du répertoire courant
et :
$
su -#
cd /tmp#
rm # ici l'alias à rm n'existe plus et vous effacez # tout ce qu'il y a dans /tmp
Joyeux hacking !
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.