Vous êtes sur la page 1sur 6

E3FI

ESIEE Paris

Systmes et scripts

B. Perret

TP : Shell Scripts

Remarque gnrale

Lorsque vous cherchez des informations sur Internet, n'oubliez pas que langage de shell script que nous
avons vu correspond bash. La plupart des ressources disponibles se rapporte ce langage nanmoins il
est possible que vous tombiez de temps en temps sur un autre langage de shell script.

Mise en jambe

Objectifs : savoir crire et excuter un shells script minimal. savoir utiliser des variables et excutez des
commandes.
Cours : slides 61 71.
Hello World :
crivez un script qui ache le message "Hello World". Excutez le et vriez que le
rsultat est conforme.

crivez un script qui prend un paramtre et ache la valeur de se paramtre l'cran.


Exemple la commande ./monscript toto doit acher parametre : toto. Excutez le et vriez que le
rsultat est conforme.
Paramtre :

Somme de deux nombres :

paramtres et l'ache l'cran.

crivez un script qui calcule la somme de deux nombres passs en

Avec des si

Objectifs : savoir utiliser la structure conditionnelle et la commande test en shell script.


Cours : slides 72 78
Max :

Ecrivez un script qui prend deux nombre en paramtre et ache le plus grand des deux.

Reprenez le script de l'exercice Paramtre ci-dessus. Que se passe-t-il si vous


lancer le script sans indiqu de paramtre ? Ajoutez des instructions an que le script ache un message
d'erreur si l'utilisateur ne passe pas 1 et 1 seul paramtre au script.

Utilisation correcte :

crivez un petit script qui retourne la valeur 0 si le premier paramtre


reu reprsente un nombre entier et 1 sinon (utilisez grep). Astuce, parfois on ne s'intresse pas la
sortie d'une commande mais uniquement son code de retour. On peut alors rediriger la sortie de cette
commande vers le chier /dev/null qui agit comme un trou noir (tout ce qu'on met dedans est perdu
jamais).
Nombre ou pas nombre :

Nombre ou pas nombre 2 :


crivez un petit script qui demande un nombre a l'utilisateur et vrie
si les caractres donns par l'utilisateur correspondent bien un nombre.

Boucles

Objectifs : savoir utiliser la structure conditionnelle et la commande test en shell script.


Cours : slides 79 86
Liste des paramtres :

crivez un script qui ache tous les paramtres qu'il a reu.

Somme de n nombres :

paramtres.

crivez un script qui calcule la somme de tous les nombres passs en

Nombre impairs :
crivez un script qui ache la liste des n premiers nombres impaires ( partir de
1), n tant un paramtre optionnel qui sera x 10 si il n'est pas prcis par l'utilisateur.

crivez un script nomm table permettant d'acher des tables de multiplications. table 5 10 aura pour rsultat l'achage :
Table de multiplication :

0 x 5 = 0
1 x 5 = 5
2 x 5 = 10
3 x 5 = 15
4 x 5 = 20
5 x 5 = 25
6 x 5 = 30
7 x 5 = 35
8 x 5 = 40
9 x 5 = 45
10 x 5 = 50
crivez un script applique.sh qui prend en paramtre le nom d'une commande et qui appelle successivement cette commande avec chacun des chiers contenu dans le rpertoire
courant. (Par exemple si le rpertoire courant contient 2 chiers fich1.txt et fich2.txt, l'excution de
./applique.sh wc gnrera les appelles : wc fich1.txt et wc fich2.txt.)
Fonction application :

crivez un script qui ache la liste des utilisateurs dont l'UID est plus
grand qu'un nombre donn en paramtre (cette information se trouve dans le chier /etc/passwd)
Qui sont les plus grands ? :

crivez un script pointer.sh qui ajoute une ligne


contenant : le login de la personne excutant le script, la date et l'heure, la n du chier pointage.sh.
Imaginons que ce script doit tre appel par les employs d'une entreprise lorsqu'ils arrivent ou quittent
leur poste. Un problme se pose : comment faire pour que le script pointer.sh puisse modier le chier
pointage.sh sans que les utilisateurs n'en aient le droit ? Ceci est a priori impossible car lorsqu'un
utilisateur lance un script, celui-ci s'excute avec les droits de l'utilisateur qui le lance. Il existe nanmoins
une astuce pour parvenir cette n : cherchez des informations sur le mot Setuid sur Internet pour trouver
la solution. Vrier avec un de vos collgues que cette solution fonctionne bien.
Pointage et gestion des droits : (optionnel)

Un peu plus complexe

Objectifs : perfectionnement et rutilisation de l'ensemble des notions vues.


crivez un script qui prend en paramtre un nom de chier et qui ache ce chier ligne
par ligne, en ajoutant devant chaque ligne : le numro de la ligne et le nombre de mots qu'elle contient.

Comptage :

crivez un script qui ache la liste de tous les chiers contenus dans le rpertoire courant,
ses sous-rpertoires, les sous-sous-rpertoires, etc.
ls rcursif :

Archivage :
crivez un script qui ralise les actions suivantes :
 Il cr le dossier ~/archive/YYYY-MM-DD/ ou YYYY-MM-DD-hh:mm est replac par la date et l'heure
actuelle (si le dossier ~/archive/ n'existe pas, il est cr dans la foule).
 Il dplace tous les chiers du rpertoire courant (ainsi que ses sous-dossiers) dans ce nouveau dossier.
Ajoutez ensuite une option pour demander au script de mettre l'ensemble des chiers dplacer dans
une archive compresse .tgz (utilitaire tar).

ouvrez le script systme /etc/init.d/killprocs qui est appel


lors de l'extinction du systme. Essayez de comprendre comment il fonctionne.
Un script de pro : (optionnel)

Problme (presque) concret : automatisation

Objectif : savoir combiner les comptences acquises pou rsoudre un problme concret, utiliser les fonctions.
Cours : slides 87 89.
Cet exercice constitue un petit problme classique : comment automatiser une tche rptitive tout en
grant proprement les exceptions.
Dans notre problme, nous avons un ensemble de donnes qui sont stockes dans le rpertoire ~perretb/public_html/I3FM/Unix/subwork/. Ces donnes sont stockes dans un peu plus
de 1200 chiers indpendants. Nous souhaitons appliquer le programme qui a t dvelopp
par l'quipe sur chacun de ces chiers. Ce programme appel doSomething est disponible ici :
~perretb/public_html/I3FM/Unix/doSomething.

doSomething n'est pas encore parfaitement able (c'est la beta 0.92) et il arrive qu'il soit incapable de
faire ce qu'il est sens faire sur certaines donnes. Nanmoins les ingnieurs ont trouv un compromis,
doSomething peut fonctionner selon 3 niveaux d'optimisation. Dans le niveau le plus haut il est trs
rapide mais plante souvent, dans le niveau le plus bas il est plutt lent mais plante rarement. La stratgie
retenue est alors la suivante : pour chaque chier on essaye de le traiter avec le niveau 1 (optimisation
maximale). Si cela ne fonctionne pas on ressaye avec le niveau 2. Si cela ne fonctionne toujours pas, on
passe au niveau 3. Finalement, si le niveau 3 ne fonctionne pas non plus, il faut enregistrer le nom du
chier fautif pour que l'quipe de dbogage se penche dessus.
Concrtement, le programme doSomething s'utilise de la faon suivante. Il prend obligatoirement 2 paramtres :
 le premier indique le niveau d'optimisation : -o1 (optimisation leve) -o2 (optimisation moyenne) -o3
(optimisation faible)
 le nom du chier traiter.
Si le traitement se droule correctement, le rsultat est crit sur la sortie standard et le code de retour 0
(succs) est renvoy. Si une erreur survient (erreur dans la faon d'utiliser le programme ou impossibilit
de traiter le chier indiqu au niveau d'optimisation voulu), le descriptif de l'erreur est crit sur la sortie
d'erreur et le code de retour 1 (chec) est renvoy.

Comme il est impensable de devoir grer cette procdure manuellement sur les 1223 chiers traiter,
vous allez devoir crire un script qui automatise le processus et enregistre les rsultats au fur et mesure.
1) Commencez par crire une fonction qui prend trois arguments :
 Le nom du chier traiter
 Le nom du chier de rsultats
 Le nom du chier de log des erreurs
Cette fonction applique la stratgie de traitement dcrite sur le chier d'entre. Le rsultat (si une
des niveaux d'optimisation fonctionne) doit tre inscrit la suite du chier de rsultats. Si le niveau
d'optimisation 3 choue, le message d'erreur produit par le programme doit tre enregistr dans le log
d'erreur (on ne s'intresse pas au message d'erreur des niveaux 1 et 2).
2) crivez un seconde fonction qui prend les mmes arguments que la fonction prcdente et qui dtermine
si le chier a dj t trait. Elle doit retourner :
 0 si le chier n'apparait ni dans le chier de rsultat ni dans le chier de log d'erreur
 1 dans le cas contraire
3) crivez le script bas sur ces deux fonctions qui automatise le traitement de tous les chiers contenu
dans le rpertoire dont il reoit le nom en paramtre. (Faites une boucle sur l'ensemble des chier du
rpertoire, dterminez alors si une action est raliser grce la fonction 2) et si c'est le cas utilisez la
fonction 1) )

Jeux du pendu

Objectif : s'amuser en shell script.


Le pendu est un jeu consistant trouver un mot en devinant quelles sont les lettres qui le composent. Au
dbut du jeu, les caractres du mot trouver sont cachs et le joueur ne peut voir que le nombre total de
caractres qui le compose. A chaque tape du jeu, le joueur propose un caractre. Si ce caractre apparait
dans le mot, toutes les lettres correspondant ce caractre sont dcouvertes (montres au joueur). Si la
lettre n'apparait pas dans le mot, le joueur perd une vie. Le joueur doit dcouvrir toutes les lettres du
mot avant de perdre toutes ses vies.
Le but de cet exercice est de programmer le jeux du pendu en shell script. Ce type de jeu est bien adapt
ce langage car il s'agit essentiellement de manipuler des chaines de caractres.
Pour commencer, rcuprez le chier ~perretb/public_html/I3FM/Unix/liste.txt qui contient une
liste de mots.
Pour coder le jeux du pendu nous allons suivre le schma suivant. Le programme va maintenir une liste des
caractres cachs. Au dbut cette liste contient toutes les lettres de l'alphabet (caches="abcd...wxyz").
A partir de cette liste et du mot a trouver, nous allons dnir diverses fonctions :
 une fonction qui remplace les lettres caches du mot dcouvrir par un autre caractre (par exemple
un tiret -)
 une fonction qui teste si le mot contient un caractre donn (pour dterminer si le joueur perd une vie)
 une fonction qui retire un caractre de la liste des caractres cachs
 une fonction qui teste si le mot ne contient aucune des lettres caches (dans ce cas le joueur gagne)
 et nalement une fonction qui tire un mot au hasard dans la liste des mots.
On va crire ces direntes tapes, l'une aprs l'autre. Testez chaque fonction aprs l'avoir crite et assurez
vous qu'elle fonctionne correctement dans des cas varis avant de passer la fonction suivante.
1) crivez une fonction motAuHasard qui ache un mot tir au hasard dans le chier
liste.txt (la variable RANDOM permet de gnrer des nombres alatoires. Par exemple
$(( RANDOM % nombdredelignes )) calcule un nombre au hasard compris entre 0 et nombrelignes
2) crivez une fonction afficheMot qui prend deux arguments : le mot trouver et la liste des lettres
caches. Cette fonction remplace dans le mot trouver toutes les lettres de la liste des lettres caches par
des tirets et ache le rsultat.
3) crivez un fonction decouvre qui prend deux arguments : la liste des caractres cachs et un caractre.
Cette fonction supprime le caractre de la liste des caractres cachs et ache la nouvelle liste.
4

4) crivez une fonction testPresence qui prend deux paramtres : le mot dcouvrir et un caractre.
Cette fonction retourne 0 si le caractre est prsent dans le mot dcouvrir et 1 sinon.
5) crivez une fonction testGagne qui prend deux arguments : le mot trouver et la liste des lettres
caches. Cette fonction retourne 0 si le mot ne contient aucun caractre cach et 1 sinon.
6) Vous pouvez maintenant crire la partie principale du jeu en combinant les fonctions prcdentes. Si
vous tes perdus, vous pouvez suivre le pseudo code donn sur la page suivante mais essayez d'abord de
trouver par vous-mme.

vie := 7
caches := "abcdefghijklmnopqrstuvwxyz"
lemot := motAuHasard()
tant que ( vie > 0 )
faire
afficheMot()
demander un caractre c l'utilisateur
caches := decouvre(caches,c)
si testPresence(mot,c) == 0
si testGagne(mot,caches)
Afficher("Gagn!")
Quitter
fin si
sinon
vie := vie - 1
fin si
fin tant que
Afficher("perdu!")