Fonctions et alias sous bash

Gazette Linux n°53 — Mai 2000

Pierre Tane

Adaptation française 

Frédéric Marchal

Correction du DocBook 

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

Alias
Une introduction aux fonctions
Un dernier avertissement

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.

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.

Une introduction aux fonctions

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

Un dernier avertissement

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 !

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.