II) L'art de scripter
Dans la partie précédente, nous avons vu l'exemple de 2 scripts assez simples. Il est néanmoins possible de réaliser des scripts plus avancés.
Pour ça, il est important de connaître le plus possible les possibilités offertes par le shell.
Une chose primordiale, et de connaître le fonctionnement des commandes que vous souhaitez utiliser dans votre script, pour ça rien de mieux qu'un petit coup de « man [commande] ».
1)Les variables particulières
Nous avons commencé à voir les variables particulières avec le deuxième script. Nous allons maintenant approfondir cet aspect.
$# correspond donc au nombre de paramètres passés au script (ou à la fonction)
$* contient la liste de tous les paramètres passés au script (ou à la fonction)
$1 contient la valeur du premier paramètre
.
.
.
$9 contient la valeur du neuvième paramètre
Je vous avez dit que pour le dixième (et plus) il y avait une petite subtilité, la voici :
${n} contient la valeur du n-ième paramètre
$? contient le code de retour de la dernière commande exécutée
Voilà pour les principaux.
Il existe également $$ qui contient le pid du processus courant, et $! qui contient le pid du dernier processus lancé en background (avec le &).
2)Les variables
Nous avons vu comment affecter des variables « en dur », ainsi que les conventions de nommage des variables. Il faut savoir que vous pouvez très bien placer le résultat d'une commande dans une variable.
MON_HOME=$(ls $HOME);
/!\ Attention: il n'y a jamais d'espace « » lors d'une affectation de valeur /!\
Désormais, un
echo "$MON_HOME"
sera équivalent à un
ls $HOME
Dans cet exemple, j'ai également utilisé une variable système, il en existe plusieurs telle que $HOME, $USER, $PWD, etc. (une liste plus complète en bas de cette page : http://doc.ubuntu-fr.org/variables_d_environnement ).
Il est également possible d'utiliser des tableaux.
tab[0]=1;
tab[1]=2;
tab[2]=3;
Pour afficher une valeur du tableau, ${tab[n]} (n étant le rang que l'on souhaite afficher).
${tab[*]} affiche tout le tableau, dans notre cas :
1 2 3
${#tab[*]} affiche lui la taille du tableau, ici 3.
Pour afficher la taille de la chaîne de caractères contenue dans une case du tableau, ${#tab[n]} (n étant l'indice de la case choisie).
Cette dernière écriture, permet également de connaître la taille de n'importe quelle variable, exemple :
MA_CHAINE="toto";
echo ${#MA_CHAINE}; # affiche 4
« $ » étant un caractère spécial, si vous souhaiter l'utiliser comme un caractère standard, il vous suffit d'utiliser un caractère inhibiteur : le back-slash « \ »
Exemple :
echo "Cette guitare coûte \$500"; # affiche « Cette guitare coûte $500 »
3) Les commentaires
Pour les commentaires, rien à ajouter.
Rappel de l'exemple:
- ceci est un commentaire
DATE=$(date); # j'explique ce que je fais
4) Les fonctions
En shell, la définition de fonctions se fait de la sorte :
nom_de_ma_fonction() {
commande 1;
commande 2;
.
.
.
return 0;
}
Comme pour notre script, notre fonction renvoie un code de retour, mais cette fois-ci avec le mot clé « return ». Un « exit » fonctionnerait mais ce dernier quitte le script.
Il est possible de passer des paramètres à notre fonction, qui seront nommés avec les mêmes convention que celles que nous avons vues plus haut. Attention donc à ne pas les confondre avec les paramètres de notre script.
L'astuce que j'utilise est d'appeler ma fonction avec le paramètre $* si j'ai besoin d'utiliser les paramètres de mon script.
Exemples d'utilisation :
ma_fonction $*;
ma_fonction $2;
ma_fonction toto titi tata;
ma_fonction;
(?) Si vous désirez utiliser ET les paramètres de votre script, ET des paramètres spécifiques à votre fonction, affectez les paramètres de votre script à des variables qui seront accessibles depuis votre fonction.
5) Les structures courantes
Autrement dit, les boucles et les if.
if [ mon test ]
then
echo "success";
else
echo "failed";
fi
while true
do
# boucle infinie
done
Il existe également des boucles for, mais je ne les maîtrise pas :-/ .
Autre structure très utile, le « case »
case $1 in
"-h"|"--help" )
# on affiche l'aide
;;
"-v"|"--version" )
# on affiche la version
;;
* )
# le paramètre n'est pas reconnu
;;
esac
Pour les tests, c'est expliqué plus haut.
Ce qu'il faut savoir, c'est que le if et le while fonctionnent avec les code de retour, il ne vous est donc pas indispensable d'utiliser un test, vous pouvez exécuter une commande, et selon qu'elle réussis ou non, vous effectuez votre traitement.
Exemple :
if cd ~/toto ; then
echo "on est dans le répertoire toto";
else
echo "le répertoire toto n'existe pas";
fi
Cet exemple n'est pas forcement des plus pertinent parce que la commande test permet d'effectuer cette vérification, mais c'était juste pour illustrer.
Enfin, une dernière chose qui peut vous être utile dans les boucles, c'est l'incrémentation ;-)
Ceci est réalisable à l'aide de la commande let (man let) simplifiée par (( )) :
(( i +=1 ))
/!\ Ici également les espaces sont important puis qu'il s'agit d'une commande /!\
Même remarque que pour les tests, les parenthèses sont là pour simplifier/clarifier le code, mais si on désire avoir un code le plus portable possible, il est préférable d'utiliser la commande let voire la commande expr.
Et voilà, on a terminé avec la partie 2