Table des matières
Résumé
Dans ce chapitre nous traiterons de l'emploi de conditions dans les scripts Bash. Ceci comprend les sujets suivants:
L'instruction if
L'usage du statut d'exécution d'une commande
Comparer et tester les entrées et des fichiers
les blocs if/then/else
Les blocs if/then/elif/else
Utiliser et tester les paramètres positionnels
Les instructions if imbriquées
Les expressions booléennes
Utiliser les instructions case
A certain moment vous pouvez vouloir donner une alternative au traitement effectué par le script, en fonction de l'échec ou la réussite d'une commande. Le bloc if permet de spécifier de telles conditions.
La syntaxe la plus compacte de la commande if est:
if TEST-COMMANDS; then CONSEQUENT-COMMANDS; fi
La liste TEST-COMMAND est exécutée, et si elle retourne le statut zéro, la liste CONSEQUENT-COMMANDS est exécutée. Le statut retourné est le statut d'exécution de la dernière commande exécutée, ou zéro si aucune condition n'est vraie.
Le TEST-COMMAND souvent comprend des comparaisons de numériques ou de chaînes, mais cela peut être aussi toute commande qui retourne un statut à zéro quand elle s'est bien exécutée et d'autres valeurs en cas d'échec. Une expression unaire est souvent utilisée pour examiner le statut d'un fichier. Si l'argument FILE d'une de ces primitives est de la forme /dev/fd/N, alors le descripteur de fichier « N » est contrôlé. stdin, stdout et stderr et leur descripteur de fichier respectif peuvent aussi être employés dans les tests.
Le tableau ci-dessous contient un aperçu de ce qu'on appelle « primitives » et qui servent aux commandes TEST-COMMAND ou liste de commandes. Ces primitives sont mises entre crochets pour indiquer le test d'une expression conditionnelle..
Tableau 7.1. Expressions primitives
| Primitives | sens |
|---|---|
[ -a FICHIER ] | Vrai si FICHIER existe. |
[ -b FICHIER ] | Vrai si FICHIER existe et est un fichier de type bloc. |
[ -c FICHIER ] | Vrai si FICHIER existe et est un fichier de type caractère. |
[ -d FICHIER ] | Vrai si FICHIER existe et est de type répertoire. |
[ -e FICHIER ] | Vrai si FICHIER existe. |
[ -f FICHIER ] | Vrai si FICHIER existe et est un fichier régulier. |
[ -g FICHIER ] | Vrai si FICHIER existe et son bit SGID est positionné. |
[ -h FICHIER ] | Vrai si FICHIER existe et est un lien symbolique. |
[ -k FICHIER ] | Vrai si FICHIER existe et son bit collant est positionné. |
[ -p FICHIER ] | Vrai si FICHIER existe et est un tube nommé (FIFO). |
[ -r FICHIER ] | Vrai si FICHIER existe et est lisible. |
[ -s FICHIER ] | Vrai si FICHIER existe et a une taille supérieure à zéro. |
[ -t FD ] | Vrai si le descripteur de fichier FD est ouvert et qu'il se réfère à un terminal. |
[ -u FICHIER ] | Vrai si FILE existe et son bit SUID (Set User ID) est positionné. |
[ -w FICHIER ] | Vrai si FICHIER existe et peut être écrit. |
[ -x FICHIER ] | Vrai si FICHIER existe et est exécutable. |
[ -O FICHIER ] | Vrai si FICHIER existe et appartient à l'identifiant effectif de l'utilisateur. |
[ -G FICHIER ] | Vrai si FICHIER existe et appartient à l'identifiant effectif du groupe. |
[ -L FICHIER ] | Vrai si FICHIER existe et est un lien symbolique. |
[ -N FICHIER ] | Vrai si FICHIER existe et qu'il a été modifié depuis qu'il a été lu. |
[ -S FICHIER ] | Vrai si FICHIER existe et est un connecteur réseau (socket). |
[ FILE1 -nt FILE2 ] | Vrai si FILE1 a été modifié plus récemment que FILE2, ou si FILE1 existe et FILE2 n'existe pas. |
[ FILE1 -ot FILE2 ] | Vrai si FILE1 est plus ancien que FILE2, ou si FILE2 existe et FILE1 non. |
[ FILE1 -ef FILE2 ] | Vrai si FILE1 et FILE2 se réfère à la même entité et même numéro d'inode. |
[ -o OPTIONNAME ] | Vrai si l'option Shell « OPTIONNAME » est activée. |
[ -z STRING ] | Vrai si la longueur de « STRING » est zéro. |
[ -n STRING ] or [ STRING ] | Vrai si la longueur de « STRING » n'est pas zéro. |
| [ STRING1 == STRING2 ] | Vrai si les chaînes sont identiques. « = » peut être employé au lieu de « == » pour une stricte compatibilité POSIX. |
| [ STRING1 != STRING2 ] | Vrai si les chaînes ne sont pas égales. |
| [ STRING1 < STRING2 ] | Vrai si « STRING1 » précède « STRING2 » selon le lexique du paramétrage local. |
| [ STRING1 > STRING2 ] | Vrai si « STRING1 » suit « STRING2 » selon le lexique du paramétrage local. |
| [ ARG1 OP ARG2 ] | « OP » est -eq, -ne, -lt, -le, -gt ou -ge. Ces opérateurs arithmétiques binaires renvoient vrai si « ARG1 » est égal, non égal, inférieur, supérieur ou égal, supérieur, ou supérieur ou égal à « ARG2 », respectivement. « ARG1 » et « ARG2 » sont des entiers. |
Les expressions peuvent être combinées avec les opérateurs suivants dans l'ordre de leur préséance:
Tableau 7.2. Combinaison d'expressions
| Opération | Effet |
|---|---|
| [ ! EXPR ] | Vrai si EXPR est faux. |
| [ ( EXPR ) ] | Renvoie la valeur de EXPR. Ceci peut être utilisé pour modifier la préséance normale des opérateurs. |
| [ EXPR1 -a EXPR2 ] | Vrai si EXPR1 et EXPR2 sont vrai.. |
| [ EXPR1 -o EXPR2 ] | Vrai si soit EXPR1 ou EXPR2 est vrai. |
L'intégrée [ (ou test) évalue les expressions conditionnelles en utilisant un jeux de règles basé sur le nombre d'arguments. Plus d'information sur ce sujet se trouve dans la documentation Bash. Tout comme le if est terminé par fi, le crochet ouvrant devrait être fermé après que les conditions aient été listées.
La liste CONSEQUENT-COMMANDS qui suit l'instruction then peut être toute commande UNIX valide , tout programme exécutable, tout script Shell exécutable ou toute instruction Shell, à l'exception de fi. Il est important de se rappeler que then et fi sont considérés comme des instructions à part entière dans le Shell. De ce fait, quand elles sont fournies à la ligne de commande, elles sont séparées par un point-virgule.
Dans un script, les différentes parties de l'instruction if sont d'ordinaire bien séparées. Ci-dessous, quelques exemples.
Le premier exemple contrôle l'existence d'un fichier:
anny ~>catmsgcheck.sh#!/bin/bash echo "Ce script vérifie si le fichier des messages existe." echo "Vérification..." if [ -f /var/log/messages ] then echo "/var/log/messages existe." fi echo echo "...fait."anny ~>./msgcheck.sh Ce script vérifie si le fichier des messages existe. Vérification... /var/log/messages existe. ...fait.
A ajouter dans vos fichier de configuration Bash:
# Ces lignes affichent un message si l'option noclobber option est positionnée: if [ -o noclobber ] then echo "Vos fichiers sont protégés contre une réécriture accidentelle du fait d'une redirection." fi
L'exemple ci-dessus fonctionnera si il est soumis à la ligne de commande:
anny ~>if[ -o noclobber ]; then echo ; echo"Vos fichiers sont protégés contre une réécriture."; echo ; fi Vos fichiers sont protégés contre une réécriture.anny ~>
Cependant, si vous employez les tests de conditions qui dépendent de l'environnement, vous pourriez obtenir des résultats variables alors que vous exécutez la même commande dans un script, parce que le script ouvrira un nouveau Shell, dans lequel les variables et options attendues pourraient ne pas être définies automatiquement.
La variable ? stocke le statut d'exécution de la commande précédemment exécutée (le processus le plus récemment achevé au premier plan).
L'exemple suivant montre un simple test:
anny ~>if[ $? -eq 0 ]More input>then echo'That was a good job!'More input>fi That was a good job!anny ~>
L'exemple suivant démontre que TEST-COMMANDS pourrait être toute commande UNIX qui retourne un statut, et le if à son tour renvoie un statut à zéro:
anny ~>if! grep $USER/etc/passwdMore input>then echo"votre compte utilisateur ne se trouve pas sur le système local"; fi votre compte utilisateur ne se trouve pas sur le système localanny >echo$?0anny >
Le même résultat peut être obtenu comme ceci:
anny >grep$USER/etc/passwdanny >if[ $? -ne 0 ]; then echo"pas un compte local"; fi pas un compte localanny >
Les exemples ci-dessous emploient des comparaisons numériques:
anny >num=`wc -l work.txt`anny >echo$num201anny >if[ "$num" -gt "150" ]More input>then echo ; echo"vous avez assez travaillé pour aujourd'hui."More input>echo ; fi vous avez assez travaillé pour aujourd'hui.anny >
Ce script est exécuté par cron chaque dimanche. Si le numéro de semaine est pair, cela vous rappelle le passage des éboueurs :
#!/bin/bash # Calculer le numéro de semaine à partir de la commande date: WEEKOFFSET=$[ $(date +"%V") % 2 ] # Tester si il y a un reste. Si pas de reste, c'est une semaine paire donc envoyer un message. # Sinon, ne rien faire. if [ $WEEKOFFSET -eq "0" ]; then echo "Dimanche soir, les éboueurs passent." | mail -s "Les éboueurs passent" your@your_domain.org
Un exemple de comparaison de chaînes avec le test de l'identifiant utilisateur:
if [ "$(whoami)" != 'root' ]; then
echo "Vous ne détenez pas la permission de lancer $0 en tant que non administrateur."
exit 1;
fi
Avec Bash, vous pouvez raccourcir ce type de construction. L'équivalent compact du test ci-dessus est ce qui suit:
[ "$(whoami)" != 'root' ] && ( echo vous êtes connectés avec un compte non administrateur; exit 1 )
Similaire à l'expression « && » qui indique quoi faire si le test s'avère vrai, « || » spécifie quoi faire si le test est faux.
Une expression régulière peut être employée aussi dans les comparaisons:
anny >genre="féminin"anny >if[[ "$genre" == f* ]]More input>then echo"Très honoré, Madame."; fi Très honoré, Madame.anny >
La plupart des programmeurs préféreront employer l'intégrée test qui est équivalent à l'emploi du crochet de comparaison, comme ceci:
test "$(whoami)" != 'root' && (echo vous êtes connectés avec un compte non administrateur; exit 1)
Voir les pages info de Bash pour plus de détails sur la correspondance de patron avec les blocs « (( EXPRESSION )) » et « [[ EXPRESSION ]] ».
Voici la construction à employer pour que le cours du traitement s'oriente d'une façon si la commande if renvoie vrai, et d'une autre si elle renvoie faux. Un exemple:
freddy scripts>genre="masculin"freddy scripts>if[[ "$genre" == "f*" ]]More input>then echo"Très honoré, Madame."More input>else echo"Comment se fait-il que le verre de Madame soit vide?"More input>fi Comment se fait-il que le verre de Madame soit vide?freddy scripts>
De même que la liste CONSEQUENT-COMMANDS suivant le then, la liste ALTERNATE-CONSEQUENT-COMMANDS suivant le else peut contenir toute commande de style UNIX qui retourne un statut d'exécution.
Un autre exemple, tiré de celui de la Section 1.2.1, « Tester le statut d'exécution »:
anny ~>su-Password:[root@elegance root]#if! grep ^$USER/etc/passwd1>/dev/null>then echo"votre compte utilisateur ne se trouve pas sur le système local">else echo"votre compte utilisateur ne se trouve pas sur le système local">fi votre compte utilisateur se trouve dans /etc/passwd file[root@elegance root]#
Nous permutons vers le compte root pour montrer l'effet du else - votre root est d'ordinaire un compte local tandis que votre compte personnel peut être géré par un système central, tel qu'un serveur LDAP.
Au lieu de déclarer une variable puis d'exécuter un script, il est fréquemment plus élégant de mettre la valeur de la variable dans la ligne de commande.
Pour ce faire nous employons les paramètres positionnels $1, $2, ..., $N. $# mémorise le nombre de paramètres de la ligne de commande. $0 mémorise le nom du script.
Voici un exemple simple:
Voici un autre exemple avec 2 paramètres:
anny ~>catweight.sh#!/bin/bash # Ce script affiche un message au sujet de votre poids si vous donnez votre # poids en kilos et votre taille en centimètres. weight="$1" height="$2" idealweight=$[$height - 110] if [ $weight -le $idealweight ] ; then echo "Vous devriez manger un peu plus gras." else echo "Vous devriez manger un peu plus de fruits." fianny ~>bash-xweight.sh55 169+ weight=55 + height=169 + idealweight=59 + '[' 55 -le 59 ']' + echo 'Vous devriez manger un peu plus gras.' Vous devriez manger un peu plus gras.
L'exemple suivant montre comment changer le script précédent de sorte qu'il affiche un message si plus ou moins de 2 paramètres sont donnés:
anny ~>catweight.sh#!/bin/bash # Ce script affiche un message au sujet de votre poids si vous donnez votre # poids en kilos et votre taille en centimètres. if [ ! $# == 2 ]; then echo "Usage: $0 poids_en_kilos taille_en_centimètres" exit fi weight="$1" height="$2" idealweight=$[$height - 110] if [ $weight -le $idealweight ] ; then echo "Vous devriez manger un peu plus gras." else echo "Vous devriez manger un peu plus de fruits." fianny ~>weight.sh70 150Vous devriez manger un peu plus de fruits.anny ~>weight.sh70 150 33Usage: ./weight.sh poids_en_kilos taille_en_centimètres
Le premier paramètre est référencé par $1, le second par $2 et ainsi de suite. Le nombre total de paramètres est stocké dans $#.
Consulter la Section 2.5, « Emploi de l'instruction exit et du if » pour voir une façon plus élégante d'afficher des messages de mode d'emploi.
Le test est fait dans beaucoup de scripts, parce que il n'y a pas d'intérêt à lancer un programme si vous savez qu'il ne va pas fonctionner:
#!/bin/bash
# Ce script donne des informations au sujet d'un fichier.
FILENAME="$1"
echo "Properties for $FILENAME:"
if [ -f $FILENAME ]; then
echo "Size is $(ls -lh $FILENAME | awk '{ print $5 }')"
echo "Type is $(file $FILENAME | cut -d":" -f2 -)"
echo "Inode number is $(ls -i $FILENAME | cut -d" " -f1 -)"
echo "$(df -h $FILENAME | grep -v Mounted | awk '{ print "On",$1", \
which is mounted as the",$6,"partition."}')"
else
echo "Le fichier est non-existant."
fi
Notez que le fichier est référencé au moyen d'une variable; dans ce cas c'est le premier paramètre du script. Alternativement, quand aucun paramètre n'est donné, l'emplacement du fichier est mémorisé généralement dans une variable au début du script, et son contenu est connu par l'invocation de la variable. De sorte que si vous voulez changer le nom d'un fichier dans un script, vous n'avez que à le modifier une fois.
C'est la forme complète de l'instruction if:
if TEST-COMMANDS; then
CONSEQUENT-COMMANDS;
elif MORE-TEST-COMMANDS; then
MORE-CONSEQUENT-COMMANDS;
else ALTERNATE-CONSEQUENT-COMMANDS;
fi
La liste TEST-COMMANDS est exécutée, et si son statut d'exécution est zéro, la liste CONSEQUENT-COMMANDS est exécutée. Si TEST-COMMANDS renvoie un statut différent de zéro, chaque liste elif est exécutée à son tour, et si leur statut d'exécution est zéro, le MORE-CONSEQUENT-COMMANDS correspondant est exécuté et la commande se termine. Si else est suivi par une liste ALTERNATE-CONSEQUENT-COMMANDS, et que la dernière commande dans le dernier if ou elif renvoie un statut différent de zéro, alors ALTERNATE-CONSEQUENT-COMMANDS est exécuté. Le statut retourné est le statut d'exécution de la dernière commande exécutée, ou zéro si aucune condition n'est vraie.
Ceci est un exemple que vous pouvez mettre dans votre crontab pour une exécution quotidienne:
anny /etc/cron.daily>catdisktest.sh#!/bin/bash # Ce script fait un test très simple pour contrôler l'espace disque. space=`df -h | awk '{print $5}' | grep % | grep -v Use | sort -n | tail -1 | cut -d "%" -f1 -` alertvalue="80" if [ "$space" -ge "$alertvalue" ]; then echo "Au moins un de mes disques est bientôt plein!" | mail -s "daily diskcheck" root else echo "Espace disque correct" | mail -s "daily diskcheck" root fi
Comprise dans une instruction if on peut inclure une autre instruction if. Vous pouvez inclure autant de niveaux de if imbriqués que vous pouvez appréhender logiquement.
Voici un exemple testant l'année bissextile:
anny ~/testdir>cattestleap.sh#!/bin/bash # Ce script teste si nous sommes dans une année bissextile ou pas. year=`date +%Y` if [ $[$year % 400] -eq "0" ]; then echo "This is a leap year. Février a 29 jours." elif [ $[$year % 4] -eq 0 ]; then if [ $[$year % 100] -ne 0 ]; then echo "Année bissextile, Février a 29 jours." else echo "Année non bissextile. Février a 28 jours." fi else echo "Année non bissextile. Février a 28 jours." fianny ~/testdir>date Tue Jan 14 20:37:55 CET 2003anny ~/testdir>testleap.sh Année non bissextile.
Le script ci-dessus peut être abrégé avec les opérateurs booléens « AND » (&&) et « OR » (||).
Nous employons le double crochet pour tester les expressions arithmétiques, voir la Section 4.6, « L'expansion arithmétique ». Ceci est équivalent à l'instruction let. Ici, vous allez être bloqué si vous employez les crochets, si vous essayez quelque chose de la sorte $[$year % 400], parce que ici, les crochets ne représentent pas une vraie commande mais eux-mêmes.
Parmi d'autres éditeurs, gvim est l'un de ceux qui supporte les codes de couleur selon le format de fichier; de tel éditeurs sont pratiques pour pister les erreurs d'écriture.
Nous avons déjà rencontré l'instruction exit dans la Section 2.1.3, « Tester le nombre de paramètres ». Il achève l'exécution du script. Il est plus souvent utilisé si l'entrée requise de l'utilisateur est incorrecte, si une instruction a échouée ou si une autre erreur intervient.
L'instruction exit admet un argument optionnel. Cet argument est le code sous forme d'entier du statut d'exécution, qui est renvoyé au parent et stocké dans la variable $?.
Un argument à zéro signifie que le script s'est exécuté correctement. Tout autre valeur peut être employée par le programmeur pour renvoyer divers messages au parent, afin que divers traitements soit activés selon l'échec ou la réussite du processus enfant. Si aucun argument n'est donné à la commande exit, le Shell parent exploite la valeur courante de la variable $?.
Ci-dessous un exemple avec un script penguin.sh légèrement adapté, lequel renvoie son statut d'exécution vers son parent, feed.sh:
anny ~/testdir>catpenguin.sh#!/bin/bash # Ce script vous laisse présenter divers menus à Tux. Il ne sera heureux que # quand il aura du poisson. Nous avons aussi ajouté un dauphin et (logiquement) un chameau. if [ "$menu" == "poisson" ]; then if [ "$animal" == "pingouin" ]; then echo "Hmmmmmm poisson... Tux heureux!" elif [ "$animal" == "dauphin" ]; then echo "Pweetpeettreetppeterdepweet!" else echo "*prrrrrrrt*" fi else if [ "$animal" == "pingouin" ]; then echo "Tux déteste ça. Tux veut du poisson!" exit 1 elif [ "$animal" == "dauphin" ]; then echo "Pweepwishpeeterdepweet!" exit 2 else echo "Voulez-vous lire cette affiche?!" exit 3 fi fi
Ce script est appelé depuis le suivant, qui donc exporte ses variables menu et animal:
anny ~/testdir>catfeed.sh#!/bin/bash # Ce script procède selon le statut d'exécution renvoyé par penguin.sh export menu="$1" export animal="$2" feed="/nethome/anny/testdir/penguin.sh" $feed $menu $animal case $? in 1) echo "Gaffe: Vous feriez mieux de lui donner du poisson, avant qu'il ne s'énerve..." ;; 2) echo "Gaffe: C'est à cause de gens comme vous qu'il quitte la terre tout le temps..." ;; 3) echo "Gaffe: Achetez la nourriture que le zoo fournit pour les animaux, i@**@, comment pensez-vous que nous survivons?" ;; *) echo "Gaffe: N'oubliez pas le guide!" ;; esacanny ~/testdir>./feed.shapple penguinTux déteste ça. Tux veut du poisson! Gaffe: Vous feriez mieux de lui donner du poisson, avant qu'il ne s'énerve...
Comme vous le voyez, le statut d'exécution peut être déterminé librement. Les commandes ont souvent une série de codes définis; voir le manuel du programmeur pour plus d'informations sur chaque commande.
Les instructions if imbriquées paraissent pratiques, mais dès que vous êtes confrontés à quelques variantes, cela engendre la confusion. Pour des conditions complexes, employez la syntaxe de case:
case EXPRESSION in CASE1) COMMAND-LIST;; CASE2) COMMAND-LIST;; ... CASEN) COMMAND-LIST;; esac
Chaque cas est une expression qui cible un patron. Les commandes COMMAND-LIST de la première correspondance trouvée sont exécutées. Le symbole « | » est employé pour séparer de multiples patrons, et l'opérateur « ) » termine la liste des patrons. Chaque case et ses commandes associées est appelé une clause. Chaque clause doit se terminer par « ;; ». Chaque instruction case est terminée par l'instruction esac.
Dans l'exemple, nous montrons l'emploi de case pour envoyer un message d'avertissement plus précis avec le script disktest.sh:
anny ~/testdir>catdisktest.sh#!/bin/bash # Ce script fait un test très simple pour vérifier l'espace disque. space=`df -h | awk '{print $5}' | grep % | grep -v Use | sort -n | tail -1 | cut -d "%" -f1 -` case $space in [1-6]*) Message="Tout est bon." ;; [7-8]*) Message="Commencer à songer à faire de la place. Il y a une partition qui est $space % pleine." ;; 9[1-8]) Message="Dépêchez-vous avec ce nouveau disque.. Une partition est $space % pleine." ;; 99) Message="Je suis en train de me noyer! Il y a une partition à $space %!" ;; *) Message="Il semble que je tourne avec un espace disque inexistant..." ;; esac echo $Message | mail -s "disk report `date`" annyanny ~/testdir>Vous avez un nouveau mail.anny ~/testdir>tail-16/var/spool/mail/annyFrom anny@octarine Tue Jan 14 22:10:47 2003 Return-Path: <anny@octarine> Received: from octarine (localhost [127.0.0.1]) by octarine (8.12.5/8.12.5) with ESMTP id h0ELAlBG020414 for <anny@octarine>; Tue, 14 Jan 2003 22:10:47 +0100 Received: (from anny@localhost) by octarine (8.12.5/8.12.5/Submit) id h0ELAltn020413 for anny; Tue, 14 Jan 2003 22:10:47 +0100 Date: Tue, 14 Jan 2003 22:10:47 +0100 From: Anny <anny@octarine> Message-Id: <200301142110.h0ELAltn020413@octarine> To: anny@octarine Subject: disk report Tue Jan 14 22:10:47 CET 2003 Commencer à songer à faire de la place. Il y a une partition qui est 87 % pleine.anny ~/testdir>
Bien sûr vous pourriez avoir ouvert votre programme de messagerie pour contrôler le résultat; c'est juste pour montrer que le script envoie un mail correct avec « To: », « Subject: » and « From: » header lines.
Beaucoup plus d'exemples de l'instruction case peuvent être trouvés dans le répertoire des scripts d'initialisation de votre système. Le script de démarrage emploie un case start et stop pour démarrer ou arrêter les processus du système. Un exemple théorique peut être trouvé dans la section suivante.
Les scripts d'initialisation ont souvent l'usage d'instructions case pour démarrer, arrêter et mettre en file d'attente les services du système. Voici un extrait du script qui démarre Anacron, un démon qui lance des commandes périodiquement avec une fréquence spécifiée en jours.
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status anacron
;;
restart)
stop
start
;;
condrestart)
if test "x`pidof anacron`" != x; then
stop
start
fi
;;
*)
echo $"Usage: $0 {start|stop|restart|condrestart|status}"
exit 1
esac
Les tâches à exécuter dans chaque cas, telles arrêter ou démarrer le démon, sont définies par des fonctions, dont la source est partiellement dans le fichier /etc/rc.d/init.d/functions. Voir le Chapitre 11, Fonctions pour plus d'explications.
Dans ce chapitre nous avons appris comment écrire des conditions dans un script de sorte que différentes tâches puissent être menées à bien selon le succès ou l'échec d'une commande. L'action peut être déterminée par l'emploi de l'instruction if. Ceci permet d'effectuer des comparaisons de chaînes et arithmétique, et de tester le statut d'exécution, l'entrée et les fichiers requis par le script.
Un simple test if/then/fi souvent précède des commandes dans un script Shell afin d'éviter la production de résultat, de sorte que le script peut aisément être lancé en tâche de fond ou via l'outil cron. Les conditions trop complexes sont généralement intégrées à une instruction case.
A la suite d'un test positif, le script peut explicitement informer le parent par le biais du statut exit 0. A la suite d'un échec, tout autre nombre peut être retourné. Basé sur ce code retour, le programme parent peut déterminer l'action appropriée.
Voici quelques idées pour vous lancer dans l'écriture de scripts if:
Employez un bloc if/then/elif/else qui affiche les informations du mois courant. Le script devrait afficher le nombre de jours du mois, et donner des informations sur l'année bissextile si le mois courant est février.
Faire la même chose avec une instruction case et une variante de l'usage de la commande date.
Modifier /etc/profile afin d'être accueilli par un message personnalisé quand vous vous connectez au système en tant que root.
Modifier le script leaptest.sh dans Section 2.4, « Opérations booléennes » afin qu'il nécessite un paramètre, l'année. Tester que exactement un seul paramètre est passé.
Ecrire un script appelé whichdaemon.sh qui vérifie que les démons httpd et init sont lancés sur votre système. Si un httpd est lancé, le script devrait afficher un message comme « Cette machine fait tourner un serveur WEB. » Employez ps pour contrôler les processus.
Ecrire un script qui fait la sauvegarde de votre répertoire racine sur une machine distante en utilisant scp. Le script devrait écrire son rapport dans un fichier journal, par exemple ~/log/homebackup.log. Si vous n'avez pas de seconde machine pour y copier la sauvegarde, se servir de scp pour tester la copie sur la machine locale. Ceci nécessite des clés SSH entre 2 hôtes, ou sinon vous devez fournir un mot de passe. La création de clés SSH est expliquée dans le man ssh-keygen.
Le script devrait se servir de tar cf pour la création de la sauvegarde et gzip ou bzip2 pour la décompression du fichier .tar. Mettre tous les noms de fichiers dans des variables. Mettre le nom du serveur distant et du répertoire distant dans une variable. Ce sera plus facile de réutiliser ce script ou d'y faire des modifications dans le futur.
Le script devrait vérifier l'existence d'une archive compressée. Si elle existe, la supprimer d'abord pour éviter les messages d'erreur.
Le script devrait aussi contrôler l'espace disque disponible. Avoir à l'esprit qu'à un moment donné vous pourrez avoir en même temps sur le disque les données dans votre répertoire racine, celles dans le fichier .tar et celle dans l'archive compressée. Si il n'y a pas assez d'espace, quitter avec un message d'erreur dans le fichier journal.
Le script devrait nettoyer l'archive compressée avant de se terminer.