0% ont trouvé ce document utile (0 vote)
332 vues123 pages

Shell Programming

Ce document décrit les bases de la programmation shell avec le langage bash. Il présente les éléments essentiels comme les commentaires, les variables, les opérations, les conditions if/else et les boucles for.

Transféré par

Végéta
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PPTX, PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
332 vues123 pages

Shell Programming

Ce document décrit les bases de la programmation shell avec le langage bash. Il présente les éléments essentiels comme les commentaires, les variables, les opérations, les conditions if/else et les boucles for.

Transféré par

Végéta
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PPTX, PDF, TXT ou lisez en ligne sur Scribd
Vous êtes sur la page 1/ 123

PROGRAMMATION SHELL

#!/bin/bash
next -> synchronisation des processus

A.ABBAS
Février 2017

1
Script Bash #!/bin/bash
$ nano essai.sh
• La première chose à faire dans un script shell est
d'indiquer quel shell est utilisé.
• En effet la syntaxe du langage change un peu selon
qu'on utilise sh, bash, ksh, etc.
• En ce qui nous concerne, nous souhaitons utiliser la
syntaxe de bash, plus répandu sous Linux et plus
complet que sh. Nous indiquons où se trouve le
programme bash :
#!/bin/bash
2
A insérer dans Linux2
i) Advanced ‘cp’
$ cp d1/f1 d2 # (d1 et d2 sont deux dossiers)
Conditions
d1 : (rx)
d1/f1 : (r)
d2 : (wx)

En matière d’autorisations :
$ cp file1 file2
Autorisations sur file2 =
Autorisations file1 ∩ Inverse(UMASK)
Le propriétaire et le groupe propriétaire sont ceux de l’utilisateur ayant exécuté la commande
de copie
Ex: cp /etc/passwd /home/tutu
-rwxr-xr-x tutu tutu passwd
A l’origine le fichier était ainsi : -rwxr-xr-x root root passwd

3
A insérer dans Linux2
ii) Advanced ‘mv’
$ mv d1/f1 d2
Conditions :
Dans d1 : (wx)
Dans d2 : (wx)
f1 : aucune condition

$ mv file1 file2
Les autorisations ainsi que le propriétaire et le groupe
propriétaire demeurent inchangés
4
Script Bash #!/bin/bash
• Bien que non indispensable, cette ligne permet de
s'assurer que le script est bien exécuté avec le bon shell.
En l'absence de cette ligne, c'est le shell de l'utilisateur qui
sera chargé. Cela pose un problème : si votre script est
écrit pour bash et que la personne qui l'exécute utilise
ksh, il y a de fortes chances pour que le script ne
fonctionne pas correctement !
• La ligne du sha-bang permet donc de « charger » le bon
shell avant l'exécution du script. À partir de maintenant,
vous devrez la mettre au tout début de chacun de vos
scripts
5
Script Bash #!/bin/bash
Exécution de commandes
• Après le sha-bang, nous pouvons commencer à coder.
Le principe est très simple : il vous suffit d'écrire les
commandes que vous souhaitez exécuter. Ce sont les
mêmes que celles utilisées dans l'invite de commandes !
• ls : pour lister les fichiers du répertoire.
• cd : pour changer de répertoire.
• mkdir : pour créer un répertoire.
• grep : pour rechercher un mot.
• sort : pour trier des mots.
6
Script : les commentaires
Tous les commentaires commencent par un #.

#!/bin/bash
# Affichage de la liste des fichiers
ls

7
Script : Execution
chmod +x essai.sh
./script

8
Script : Execution exemple
#!/bin/bash
ls
pwd
mkdir MyScripts MyScripts/toto2

9
Script : Exécution de débogage
$ bash -x essai.sh
• On appelle directement le programme bash et on lui ajoute en
paramètre un -x (pour lancer le mode débogage) ainsi que le
nom de notre script à déboguer.
• Le shell affiche alors le détail de l'exécution de notre script, ce
qui peut nous aider à retrouver la cause des erreurs :
$ bash -x essai.sh 
+ pwd
/home/abbas
+ ls
essai.sh

10
Affichage et manipulation des
variables

11
Déclaration des variables
#!/bin/bash
message='Bonjour tout le monde‘
echo $message
message2=‘Mon Message est : $message’
echo $message2

# Dans ce cas chaque mot est considéré


# comme un seul paramètre

12
Déclaration des variables
#!/bin/bash
message=« Bonjour tout le monde »
echo $message
message2=« Mon message = $message »
echo message2
#Dans ce cas la chaine est
# considérée comme un seul
# paramètre

13
Déclaration des variables
#!/bin/bash
message= `pwd`
echo $message

14
Read : commande de saisie
read message
echo « Bonjour $message »
read var1 var2
echo « Bonjour $var1 $var2 »

read -p 'Entrez votre nom : ' nom
echo  « Bonjour $nom ! » 

read –p 'Votre nom : ' –n 5 nom

# -t : limiter le temps autorisé pour saisir un message


read –p 'Nom (vous avez 3 secondes) : ' –t 3 code

# -s : ne pas afficher le texte saisi


read –p 'Saisir votre mot de passe : ' –s motpasse
echo –n « votre mot de passe est $motpasse »
15
More ‘d more
Follow me
$ ls –l
…….
$ echo $?
<ERROR CODE>

$ mmkkd
$echo $?
<ERROR CODE>
16
Opérations mathématiques
• En bash, les variables sont toutes des chaînes
de caractères. En soi, le bash n'est pas
vraiment capable de manipuler des nombres ;
il n'est donc pas capable d'effectuer des
opérations.
• Mais,il est possible de passer par des
commandes.
• Ici, la commande à connaître est let.

17
Opérations mathématiques
let "a = 5"
let "b = 2“
let "c = a + b“

l'addition : + ;
la soustraction : - ;
la multiplication : * ;
la division : / ;
la puissance : ** ;
le modulo (renvoie le reste de la division entière) : %.
18
Opérations mathématiques
Quelques exemples :
let "a = 5 * 3" # $a = 15
let "a = 4 ** 2" # $a = 16 (4 au carré)
let "a = 8 / 2" # $a = 4
let "a = 10 / 3" # $a = 3
let "a = 10 % 3" # $a = 1

19
Les variables d’environnement
Commandes : env
MANIP :
#!/bin/bash
cd /home/abbas
mkdir Scripts
export dossierscript=/home/abbas/Scripts
cd /etc #pour changer de repertoire
cd $dossierscript
20
Les variables des paramètres
Comme toutes les commandes, les scripts bash peuvent eux aussi
accepter des paramètres. Ainsi, on pourrait appeler notre script
comme ceci : ./variables.sh param1 param2 param3

Dans ce cas des variables sont automatiquement créées :


• $# : contient le nombre de paramètres ;
• $0 : contient le nom du script exécuté (ici ./variables.sh) ;
• $1 : contient le premier paramètre ;
• $2 : contient le second paramètre ;
• … ;
• $9 : contient le 9e paramètre.

21
Les variables des paramètres
#!/bin/bash
echo "Le paramètre 1 est $1"
shift
echo "Le paramètre 1 est maintenant $1"

22
Les tableaux
• Le bash gère également les variables « tableaux ».
• Ce sont des variables qui contiennent plusieurs cases,
comme un tableau.
• Pour définir un tableau, on peut faire comme ceci :
tableau=('valeur0'  'valeur1'  'valeur2')
• Cela crée une variable tableau qui contient trois valeurs
(valeur0, valeur1, valeur2).
• Pour accéder à une case du tableau, il faut utiliser la
syntaxe suivante :
${tableau[2]}
23
Les tableaux
On peut aussi définir manuellement le contenu d'une
case : tableau[2]='valeur2‘
Exemple :
#!/bin/bash tableau=('valeur0' 'valeur1' 'valeur2')
tableau[5]='valeur5'
echo ${tableau[1]}
On peut afficher l'ensemble du contenu du tableau
d'un seul coup en utilisant
${tableau[*]} 
24
LES CONDITIONS

25
Les conditions
• La prise de décision est un élément
indispensable dans tout programme. Si on ne
pouvait pas décider quoi faire, le programme
ferait toujours la même chose
• Les branchements conditionnels
« conditions » constituent un moyen de dire
dans notre script « SI cette variable vaut tant,
ALORS fais ceci, SINON fais cela ».

26
Les conditions : « if »
if [ test ]
then
   echo "C'est vrai"
fi
============= OUBIEN ==============
if [ test ]; then  
   echo "C'est vrai"
fi

27
Les conditions : « if »
#!/bin/bash
nom="Miloud"
if [ $nom = "Miloud" ]
then
    echo "Salut Miloud !"
fi

28
Les conditions « if »
#!/bin/bash
read –p "Entrez le nom 1"  nom1
read –p "Entrez le nom 2"  nom2

if [ $nom1 = $nom2 ]; then
   echo "Salut les jumeaux !"
fi

29
Les conditions : « if » … « else »
if [ test ]
then        
 echo "C'est vrai"
else         
echo "C'est faux"
fi

30
« if » then « else »
#!/bin/bash
nom="Ahmed"  
if [ $nom = "Ahmed" ]
then         
echo "Salut Ahmed !"
else    
echo  "Je ne te connais pas"
fi

31
if then else
#!/bin/bash
if [ $1 = "Bruno" ]
then
    echo "Salut Bruno !"
else  
     echo "J'te connais pas!"
fi

32
If then else if then else if then else
if [ test ]; then         
echo "Le premier test a été vérifié " 
elif [ autre_test ]; then         
echo "Le second test a été vérifié " 
elif [ encore_autre_test ]; then         
echo "Le troisième test a été vérifié"
else         
echo "Aucun précédents n'a été vérifié"
fi

33
Les [ tests ]
Les différents types de tests : Il est possible
d’effectuer trois types de tests différents en
bash :

• des tests sur des chaînes de caractères ;


• des tests sur des nombres ;
• des tests sur des fichiers.

34
Les tests : chaines de caractères
Condition Signification
Vérifie si les deux chaînes sont identiques. Notez que
bash est sensible à la casse : « b » est donc différent
$chaine1  =   $chaine2 de « B ».
Il est aussi possible d'écrire « == » pour les habitués
du langage C.
$chaine1  !=  $chaine2 Vérifie si les deux chaînes sont différentes.
-z  $chaine Vérifie si la chaîne est vide.
-n  $chaine Vérifie si la chaîne est non vide.

35
Les tests : chaines de caractères
Exemple :
#!/bin/bash
if [ -z $1 ]
then         
echo "Pas de paramètre"
else
     echo "Paramètre présent"   
fi
36
Les tests : nombres
Condition Signification
Vérifie si les nombres sont égaux (equal). À ne pas
$num1 -eq $num2 confondre avec le « = » qui, lui, compare deux chaînes
de caractères.
Vérifie si les nombres sont différents (nonequal).
$num1 -ne $num2 Encore une fois, ne confondez pas avec « != » qui est
censé être utilisé sur des chaînes de caractères.
$num1 -lt $num2 Vérifie si num1 est inférieur ( < ) à num2 (lowerthan).
Vérifie si num1 est inférieur ou égal ( <= ) à num2
$num1 -le $num2
(lowerorequal).
$num1 -gt $num2 Vérifie si num1 est supérieur ( > ) à num2
(greaterthan).
Vérifie si num1 est supérieur ou égal ( >= ) à num2
$num1 -ge $num2 (greaterorequal).

37
Les tests : nombres
Exemple :
#!/bin/bash
if [ $1 -ge 20 ]
then         
echo "Vous avez envoyé 20 ou plus"
else    
     echo "Vous avez envoyé moins de 20"
fi
38
Les tests : fichiers
Condition Signification
-e $nomfichier Vérifie si le fichier existe.
Vérifie si le fichier est un répertoire. N'oubliez pas que sous
-d $nomfichier Linux, tout est considéré comme un fichier, même un
répertoire !
Vérifie si le fichier est un… fichier. Un vrai fichier cette fois,
-f $nomfichier pas un dossier.
-L $nomfichier Vérifie si le fichier est un lien symbolique (raccourci).
-r $nomfichier Vérifie si le fichier est lisible (r).
-w $nomfichier Vérifie si le fichier est modifiable (w).
-x $nomfichier Vérifie si le fichier est exécutable (x).
$fichier1 -nt $fichier2 Vérifie si fichier1 est plus récent que fichier2 (newerthan).
$fichier1 -ot $fichier2 Vérifie si fichier1 est plus vieux que fichier2 (olderthan).

39
Les tests : fichiers
-s : file is not zero size
-b : file is a block device
-c : file is a character device
device0="/dev/sda2" # / (root directory) if [ -b "$device0" ] then echo "$device0 is a block device." fi #
/dev/sda2 is a block device. device1="/dev/ttyS1" # PCMCIA modem card. if [ -c "$device1" ] then echo
"$device1 is a character device." fi # /dev/ttyS1 is a character device.
-p : file is a pipe
function show_input_type() { [ -p /dev/fd/0 ] && echo PIPE || echo STDIN } show_input_type "Input" #
STDIN echo "Input" | show_input_type # PIPE # This example courtesy of Carl Anderson.
-h : file is a symbolic link
-S : file is a socket
-t : file (descriptor) is associated with a terminal device
This test option may be used to check whether the stdin [ -t 0 ] or stdout [ -t 1 ] in a given script is a terminal.
-g : set-group-id (sgid) flag set on file or directory
If a directory has the sgid flag set, then a file created within that directory belongs to the group that owns the
directory, not necessarily to the group of the user who created the file. This may be useful for a directory
shared by a workgroup.
-u : set-user-id (suid) flag set on file
A binary owned by root with set-user-id flag set runs with root privileges, even when an ordinary user
invokes it. This is useful for executables (such as pppd and cdrecord) that need to access system hardware.
Lacking the suid flag, these binaries could not be invoked by a non-root user.
-rwsr-xr-t 1 root 178236 Oct 2 2000 /usr/sbin/pppd
A file with the suid flag set shows an s in its permissions. 40
Les tests : fichiers
-O : you are owner of file
-G : group-id of file same as yours
-N : file modified since it was last read
f1 -nt f2 : file f1 is newer than f2
f1 -ot f2 : file f1 is older than f2
f1 -ef f2 : files f1 and f2 are hard links to the same file
! : "not" -- reverses the sense of the tests above
(returns true if condition absent).

41
Les tests : fichiers
-k : sticky bit set
• Commonly known as the sticky bit, the save-text-mode flag is a special
type of file permission. If a file has this flag set, that file will be kept in
cache memory, for quicker access. If set on a directory, it restricts write
permission. Setting the sticky bit adds a t to the permissions on the file or
directory listing. This restricts altering or deleting specific files in that
directory to the owner of those files.
drwxrwxrwt 7 root 1024 May 19 21:26 tmp/
If a user does not own a directory that has the sticky bit set, but has write
permission in that directory, she can only delete those files that she owns
in it. This keeps users from inadvertently overwriting or deleting each
other's files in a publicly accessible directory, such as /tmp. (The owner of
the directory or root can, of course, delete or rename files there.)

42
Les tests : fichiers
#!/bin/bash
read -p 'Entrez un répertoire : ' repertoire
if [ -d $repertoire ]
then         
echo "Bien, vous avez compris ce que j'ai dit !
else
  echo "Vous n'avez rien compris..."
fi
43
LE ++ : Check the ownership
if [ -n "$(find . -user "$username" -print -prune -o -prune)" ]; then
echo "The current directory is owned by $username."
fi
if [ -n "$(find . -user "$(id -u)" -print -prune -o -prune)" ]; then
echo "The current directory is owned by the current user."
fi

44
Check for the ownership
uname2=$(ls -l $1 | awk '{print $3}');
if [ $uname2 == $USER ]
then
echo owner
else
echo no owner
fi

45
Example : Testing for broken links
#!/bin/bash
# broken-link.sh
# Written by Lee bigelow [email protected]
# Used in ABS Guide with permission.
# A pure shell script to find dead symlinks and output them quoted
#+ so they can be fed to xargs and dealt with :)
#+ eg. sh broken-link.sh /somedir /someotherdir|xargs rm
# This, however, is a better method:
# find "somedir" -type l -print0|\
# xargs -r0 file|\
# grep "broken symbolic"|
# sed -e 's/^\|: *broken symbolic.*$/"/g'
#+ but that wouldn't be pure Bash, now would it.
# Caution: beware the /proc file system and any circular links!
################################################################
# If no args are passed to the script set directories-to-search
#+ to current directory. Otherwise set the directories-to-search
#+ to the args passed.
######################
[ $# -eq 0 ] && directorys=`pwd` || directorys=$@
# Setup the function linkchk to check the directory it is passed
#+ for files that are links and don't exist, then print them quoted.
# If one of the elements in the directory is a subdirectory then
#+ send that subdirectory to the linkcheck function.
##########
linkchk () {
for element in $1/*; do
[ -h "$element" -a ! -e "$element" ] && echo \"$element\"
[ -d "$element" ] && linkchk $element
# Of course, '-h' tests for symbolic link, '-d' for directory.
done
}
# Send each arg that was passed to the script to the linkchk() function
#+ if it is a valid directoy. If not, then print the error message
#+ and usage info.
##################
for directory in $directorys; do
if [ -d $directory ]
then linkchk $directory
else
echo "$directory is not a directory"
echo "Usage: $0 dir1 dir2 ..."
fi
done
exit $?

46
Effectuer plusieurs tests
Dans un if, il est possible de faire plusieurs tests à la
fois. En général, on vérifie :
• si un test est vrai ET qu'un autre test est vrai ;
• si un test est vrai OU qu'un autre test est vrai.
Les deux symboles à connaître sont :
&& : signifie « et » ;
if [ $1 == $2 ] && [ $1 != $3 ]; then
|| : signifie « ou ».
if [ $1 == $2 ] || [ $1 != $3 ]; then

47
Inverser un test
• Il est possible d'inverser un test en utilisant la
négation. En bash, celle-ci est exprimée par le
point d'exclamation « ! ».
Exemple :
if [ ! -e fichier ]
then     
    echo "Le fichier n'existe pas"
fi
48
Tester plusieurs conditions « case »
#!/bin/bash
case $1 in         
"Bruno")
 echo "Salut Bruno ! "  
   ;;
"Michel")
   echo "Bien le bonjour Michel "  
   ;;        
"Jean")     
   echo "Hé Jean, ça va ?"       
   ;;     
*)       
   echo "J'te connais pas!"         
   ;;
esac

49
« case »
IMPORTANT :

• Si la condition est vérifiée, tout ce qui suit est


exécuté jusqu'au prochain double point-virgule :

• Important, il ne faut pas l'oublier : le double point-


virgule dit à bash d'arrêter là la lecture du case. Il
saute donc à la ligne qui suit le esac signalant la
fin du case.
50
« case » exemple
#!/bin/bash
case $1 in         
"Chien" | "Chat" | "Souris")
          echo "C'est un mammifère"         
        ;;   
"Moineau" | "Pigeon")       
          echo "C'est un oiseau"        
         ;;    
*)      
         echo "Je ne sais pas ce que c'est"        
         ;;
esac

51
LES BOUCLES

52
• Nous allons découvrir dans ce chapitre un autre élément
de base de tous les langages : les boucles. Ces structures
permettent de répéter autant de fois que nécessaire une
partie du code. En bash, on n'y échappe pas !
• Les consignes sont les mêmes que pour le chapitre sur les
conditions : il faut être vigilant sur la syntaxe. Une espace
de trop ou de moins, l'oubli d'un caractère spécial et plus
rien ne fonctionne. Soyez donc très rigoureux lorsque vous
codez !
• Si vous suivez cette simple règle, vous n'aurez pas de
problèmes.
53
while
while [ test ]
do      
   echo 'Action en boucle‘
done
=================================
while [ test ]; do
echo 'Action en boucle'
done
54
while
Exemple :

#!/bin/bash
while [ -z $reponse ] || [ $reponse != 'oui' ]
do   
      read -p 'Dites oui : ' reponse
done

55
for
#!/bin/bash
for variable in 'valeur1' 'valeur2' 'valeur3‘
do   
      echo "La variable vaut $variable"
done

56
for
Exemple :

#!/bin/bash
contenu=`ls`
for i in $contenu
do   
      echo "Fichier trouvé : $i"
done

57
for
Exemple :

#!/bin/bash
for fichier in `ls`
do        
 echo "Fichier trouvé : $fichier"
done

58
for
#!/bin/bash
for fichier in `ls`
do        
 mv $fichier $fichier-old
done

Essayez de créer un script multirenommage.sh, reposant sur


ce principe, qui va rajouter le suffixe -old… uniquement
aux fichiers qui correspondent au paramètre envoyé par
l'utilisateur ! (*.txt) par exemple

59
For numérique
#!/bin/bash
for i in `seq 1 10`;
do  
       echo $i
done

Si on veut changer le pas d’avancement écrire :


for i in `seq 1 2 10`;
Dans ce cas, le pas d’avancement = 2
60
LA PRATIQUE

61
TP1
Ecrire un script qui demande à l'utilisateur de
saisir une note et qui affiche un message en
fonction de cette note :
– "très bien" si la note est entre 16 et 20 ;
– "bien" lorsqu'elle est entre 14 et 16 ;
– "assez bien" si la note est entre 12 et 14 ;
– "moyen" si la note est entre 10 et 12 ;
– "insuffisant" si la note est inférieur à 10.

62
TP1 : solution
#!/bin/bash echo "Entrez votre note :"
read -r note
if [ "$note" -ge 16 ]; then
echo "très bien"
elif [ "$note" -ge 14 ]; then
echo "bien"
elif [ "$note" -ge 12 ]; then
echo "assez bien"
elif [ "$note" -ge 10 ]; then
echo "moyen"
else
echo "insuffisant"
fi

63
TP2
Reprenez le TP précédant et faites en sorte que
le programme se répète tant que l'utilisateur
n'a pas saisi une note négative ou 'q' (pour
quitter).

Le script doit calculer le nombre de notes de


saisies et en faire la moyenne tout à la fin.

64
TP2 : solution
#!/bin/bash elif [ "$note" -ge 10 ]; then
note=0 echo "moyen"
moyenne=0 elif [ "$note" -ge 0 ]; then
i=0 echo "insuffisant"
until [ "$note" -lt 0 ]; do else
echo "Entrez votre note (q pour quitter) :" echo "au revoir !"
read -r note fi
if [ "$note" -ge 0 ]; then
if [ "$note" = "q" ]; then
let moyenne=$moyenne+$note
note=-1
let i=$i+1
echo "au revoir !"
fi
elif [ "$note" -ge 16 ]; then
done
echo "très bien" if [ "$i" -le 0 ]; then
elif [ "$note" -ge 14 ]; then let i=1
echo "bien" fi
elif [ "$note" -ge 12 ]; then let moyenne=$moyenne/$i
echo "assez bien" echo "La moyenne est de $moyenne ($i notes)"

65
TP3
Créer un script qui prend un nombre en saisie et l'élève à sa
propre puissance. C'est un peu le même principe que la
factorielle mais cette fois, l'usage de la boucle for est imposé.

Exemple d'exécution :

[ ~] ./NomDuScript.sh
Saisir une valeur :
2
2^2 = 4

66
TP3 : solution1
#!/bin/bash
echo "Saisir une valeur"
read -r value
result=1
for (( i=0 ; i<$value ; i++ )); do
let result=$result*$value
done
echo "$value^$value = $result"
67
TP3 : solution2
#!/bin/bash

operation () {
result=1
for (( i=0 ; i<$value ; i++ ))
do
let result=$result*$value
done
echo "$value^$value = $result"
}

if [ "$#" -eq 0 ]; then


echo "Saisir une valeur"
read -r value
else
value=$1
fi
operation

68
TP4
Reprenez uniquement la version 1 de l'exercice.
La note devra être donnée en paramètre ou
bien saisie en cas d'absences d'arguments. La
comparaison de la note devra être faite dans
une fonction appreciation().

69
TP4 : solution
#!/bin/bash # programme principal
appreciation () { clear
if [ "$note" -ge 16 ]; then if [ "$#" -ne 0 ]; then
echo "très bien" note=$1
elif [ "$note" -ge 14 ]; then else
echo "bien" echo "Saisir une note"
elif [ "$note" -ge 12 ]; then read -r note
echo "assez bien" fi
elif [ "$note" -ge 10 ]; then appreciation
echo "moyen"
else
echo "insuffisant"
fi
}

70
TP5
Créer un script qui vous propose le menu suivant
:
1 - Vérifier l'existence d'un utilisateur
2 - Connaître l'UID d'un utilisateur
q - Quitter

71
TP5 : solution
#!/bin/bash rep=1
while [ "$rep" -eq 1 ]; do
pause () { clear
echo "Appuyez sur ENTER pour continuer" printf "menu :\n\n"
read echo "1. Vérifier l'existence d'un utilisateur"
} echo "2. Connaître l'UID d'un utilisateur"
echo -e "3. Quitter\n"
saisirUser () { read -r choix
echo "Saisir l'utilisateur" case "$choix" in
1)
read -r util
saisirUser
}
verifyUser ;;
2)
verifyUser () {
saisirUser
if grep "^$util:" /etc/passwd > /dev/null; then
id $util
echo "L'utilisateur existe"
pause ;;
else q)
echo "L'utilisateur n'existe pas" echo "Au revoir"
fi pause
pause rep=0 ;;
} *)
echo "Erreur de saisie"
pause ;;
esac
done
72
TP6
Créer un script dans lequel deux nombres opérandes et un
signe opérateur (+-*/) devront être donnés en paramètres,
ou saisis. Le script doit réaliser l'opération souhaitée.

Exemple :

[ ~] ./calculette.sh 7 + 4
Le résultat est : 11

Le calcul devra être fait à l'aide d'une fonction calcul ().

73
#!/bin/bash
saisir () { TP6 : solution1
printf "Saisir le premier nombre, puis le signe de l'opération puis le deuxième nombre :\n\n"
read -r nb1
read -r s
read -r nb2
}
calcul () {
case "$s" in
"+") let result=$nb1+$nb2 ;;
"-") let result=$nb1-$nb2 ;;
"*") let result=$nb1*$nb2 ;;
"/") let result=$nb1/$nb2 ;;
*)
let result=0
echo -e "Erreur de saisie !\nLe résultat est faux.";;
esac
}
calcul2 () {
let result=$nb1$s$nb2
}
if [ "$#" -eq 3 ]; then
nb1=$1 ; s=$2 ; nb2=$3
else
saisir
fi
calcul
echo "Le résultat est $result"
calcul2
echo "Calculé d'une autre façon : $result"
74
#!/bin/bash TP6 : solution2
if [ "$#" -lt 3 ]; then
echo "Erreur : Il manque des paramètres !"
elif [[ "$1" =~ ^[0-9]+$ ]] && [[ "$3" =~ ^[0-9]+$ ]]; then
if [[ "$2" =~ ^(\+|\-|\/|\*){1}$ ]]; then
if [ $3 -ne 0 ] || [ "$2" != "/" ]; then
echo "Le résultat est : "$(( $1 $2 $3 ))
else
echo "Erreur : division par 0 !"
fi
else
echo "Erreur : opérateur invalide !"
fi
else
echo "Erreur : opérandes invalides !"
fi 75
#!/bin/sh TP6 : solution3

if [ "$#" -lt 3 ]; then


echo "Erreur : Il manque des paramètres !"
elif echo "$1$3" | grep -E "^[0-9]{2,}$" > /dev/null; then
if echo "$2" | grep -E "^(\+|\-|\/|\*){1}$" > /dev/null; then
if [ $3 -ne 0 ] || [ "$2" != "/" ]; then
echo "Le résultat est : "$(( $1 $2 $3 ))
else
echo "Erreur : division par 0 !"
fi
else
echo "Erreur : opérateur invalide !"
fi
else
echo "Erreur : opérandes invalides !"
fi
76
TP7
Créer un script qui permet de calculer et
d'afficher la factorielle d'un nombre donné en
paramètre (ou saisi en cas d'absence de
paramètres).

77
#!/bin/bash TP7 : solution1
if [ "$#" -eq 0 ]; then
echo "Saisir une valeur : "
read -r val
else
val=$1
fi
# Dans le cas où c'est négatif, on rend la valeur positive
if [ "$val" -lt 0 ]; then
let val=-1*$val
fi
result=1
val2="$val"
while [ "$val" -ne 0 ]; do
printf "$val "
let result=$result*$val
let val=$val-1
if [ "$val" -ne 0 ]; then
printf "* "
fi
done
echo "= $result"
78
#!/bin/sh TP7 : solution2
if test "$#" -eq 0; then
echo "Saisissez une valeur correcte"
read -r val
set -- $val
fi
nb=${nb:-$1}
res=${res:-1}
if test "$nb" -eq 0; then
echo $res
exit
fi
res=`expr $res \* $nb`
nb=`expr $nb - 1`
. $0

79
TP8 : fichiers
Créer un script qui doit calculer le nombre de
fichiers standard, de sous-répertoires, et
d'exécutables d'un répertoire quelconque qui
sera donné en paramètre (ou saisis en cas
d'absence du paramètre).

80
#!/bin/bash
j=0 TP8 : solution
k=0
l=0
if [ "$#" -eq 0 ]; then
echo "Saisir le répertoire"
read -r rep
else
rep=$1
fi
cd $rep
for i in *; do
if [ -d "$i" ]; then
echo "$i"
let j=$j+1
fi
if [ -f "$i" ]; then
echo $i
let k=$k+1
fi
if [ -x "$i" ]; then
echo $i
let l=$l+1
fi
done
echo "Il y a $j répertoires, $k fichiers et $l exécutables dans $rep"
81
TP9 : tri à bulle
Créer un script qui devra enregistrer à l'aide d'un
tableau, un nombre d'entiers donné en
paramètre (ou en saisie) puis trier ceux-ci dans
l'ordre croissant dans ce même tableau (sans
passer par un autre) et enfin afficher le
contenu du tableau (ordonné) sur la sortie
standard.

82
#!/bin/bash
if [ "$#" -lt 1 ]; then
echo "Saisir le nombre d'éléments à ordonner"
read -r SIZE
TP9
else
SIZE=$1
fi
echo "Saisir les éléments :"
for (( i=0 ; i<SIZE ; i++ )); do
read -r tab[i]
done
for (( i=0 ; i<SIZE ; i++ )); do
for (( j=$i+1 ; j<SIZE ; j++ ))
do
if [ "${tab[$j]}" -le "${tab[$i]}" ]; then
tampon="${tab[$i]}"
tab[$i]="${tab[$j]}"
tab[$j]="$tampon"
fi
done
done
echo "Valeurs ordonnées :"
for (( i=0 ; i<SIZE ; i++ )); do
echo "${tab[$i]}"
done 83
TP10 : ls dans l’ordre inverse
Créer un script qui renvoie la même sortie que la
commande ls mais dans l'ordre décroissant
(autrement dit : le script devra lister le
contenu d'un répertoire dans l'ordre
décroissant). Vous ne devez ni vous servir de
la commande ls, ni de la commande sort.

84
#!/bin/bash TP10 –
Solution1
# Si on a au moins un paramètre et que le premier paramètre est un répertoire
if [ "$#" -ge 1 ] && [ -d "$1v ]; then
cd $1
fi

nb=0

for fichier in *; do
tab[$nb]="$fichier"
let nb=$nb+1
done

# affichage inversé
for (( i=$nb ; i>=0 ; i=$i-1 )); do
echo ${tab[$i]}
done

85
#!/bin/bash
listing=( * )
TP10 –
for (( i=${#listing[@]}-1 ; i >= 0 ; i=i-1 )); do
echo ${listing[$i]}
Solution2
done

#!/bin/bash
read -rp 'Entrez le nom du répertoire : ' repertoire
if [ -d "$repertoire" ]; then
[[ $repertoire != */ ]] && repertoire="${repertoire:+$repertoire/}"
shopt -s nullglob #sinon repertoireVide/*, retournera repertoireVide/*
fichiers=( ${repertoire}* ) TP10 –
((${#fichiers[@]})) && {
Solution3
for (( x=${#fichiers[@]}-1; x>=0; x-- )); do
echo "${fichiers[x]}"
done
} || echo "$repertoire est vide"
else
echo "$repertoire n'est pas un répertoire"
fi 86
#!/bin/bash
read -rp 'Entrez le nom du répertoire : ' repertoire
[ -d "$repertoire" ] || { TP10 –
printf "%s n'est pas un nom de dossier valide." "$repertoire" Solution4
exit 1
}
compgen -o default "${repertoire}/" | tac

#!/bin/bash
read -rp 'Entrez le nom du répertoire : ' repertoire
[ -d "$repertoire" ] || {
printf "%s n'est pas un nom de dossier valide.\n" "$repertoire"
exit 1 TP10 –
} Solution5
text=""
while read -r; do
text="${REPLY}\n${text}"
done < <(compgen -o default "${repertoire}/")
[[ ${text} ]] && printf "$text" || printf "le dossier %s est vide.\n"
"$repertoire"
87
TP11
Créer un script devra exploiter les données d'un fichier de notes que vous aller créer au préalable
dans le même répertoire que le script. Ce fichier sera appelé FichierNote.txt comme ceci :
Dupont François 12
Durand Françoise 8
Dujardin Nicole 14
Le script devra afficher les lignes dans lesquelles la note est supérieure ou égale à 10.
Exemple :
[ ~] ./NomDuScript
Dupont François 12
Dujardin Nicole 14

#!/bin/bash
fichier="FichierNote.txt"
while read -r ligne; do
set -- "$ligne"
if [ "$3" -ge 10 ]; then
echo "$ligne"
fi
done < $fichier 88
TP12 : liste des utilisateurs
Créer un script qui prend en paramètre (ou en saisie en cas d'absence du paramètre) un fichier
qui contient des lignes comme ceci : Login + Tabulation + Nom + Tabulation + Prénom.
Exemple :
dupontf Dupont François
fdurand Durand Françoise
nicoled Dujardin Nicole

Le script devra vérifier, à l'aide d'une fonction, l'existence des utilisateurs enregistrés dans le
fichier. Admettons, par exemple, que seul Dupont François soit un utilisateur et que le fichier
se nomme ~/Documents/FichierUser, le script devra s'exécuter comme ceci :

[ ~] ./NomDuScript ~/Doucuments/FichierUser
dupontf Dupont François
[ ~] ./NomDuScript
Saisissez le fichier à traiter :
~/Documents/UserFichier
Le fichier n'existe pas.
[ ~]

Le script devra donc, au préalable, vérifier l'existence du fichier avant de comparer son contenu
au fichier /etc/passwd. Le script devra également quitter la boucle si le fichier est vide.
89
#!/bin/bash
TestUser () { TP12 solution
if grep "^$util:" /etc/passwd > /dev/null
then
echo $ligne
fi
}
if [ "$#" -eq 0 ]; then
echo "Chemin et nom du fichier :"
read -r fichier
else
fichier="$1"
fi
if [ -e "$fichier" ]; then
while read -r ligne; do
set -- "$ligne"
util="$1"
TestUser
done < $fichier
else
echo "Le fichier $fichier n'existe pas."
fi
90
TP13 : convertisseur décimal/binaire
Créer un script qui prend en paramètre (ou en saisie
en cas d'absence de paramètres) une valeur
décimale et qui doit la convertir en binaire.

Vous devez travailler sur 8 bits et chaque bit devra


être contenu dans une case d'un tableau mono-
dimensionnel et à la fin on affiche toutes les cases
de ce tableau pour avoir la valeur en binaire lisible
de droite à gauche, à partir de la valeur décimale
saisie au départ.
91
#!/bin/bash
MaxBits=8 TP13
pow () {
value2=1 Solution1
for (( k=1 ; k<$i ; k ++ )); do
let value2=$value2*2
done
}
if [ "$#" -eq 0 ]; then
echo "Saisir une valeur décimale"
read -r value
else
value="$1"
fi
declare -a bin
j=0
for (( i="$MaxBits" ; i>=0 ; i-- )); do
pow
if [ "$value" -ge "$value2" ]; then
bin[$j]="1"
let value=$value-$value2
else
bin[$j]="0"
fi
let j=$j+1
done
printf "La valeur binaire est de : "
for (( i=0 ; i<$MaxBits ; i++ )); do
printf "${bin[$i]}"
done
echo "" 92
TP13
Solution2

#!/bin/bash

unset resultat
echo "Entrez une valeur a convertir : "
read -r i
for (( cpt=8 ; $cpt > 1 ; cpt-- )); do
let resultat[$cpt]="$i & 1"
let i="i >>= 1"
done
echo "${resultat[@]}"

93
TP13
Solution3

#!/bin/bash

unset res
dec=$1
[[ $dec ]] || read -rp "Entrez une valeur a convertir : " dec
while true; do
res[$dec]=$((dec & 1))
((dec>>=1 )) || break
done
echo "${res[@]}"

94
TP14 : moyenne des notes sur un fichier
Créer un script qui prend en paramètre ou en saisie le nom d'un fichier
contenant le nom des élèves et leurs trois notes. Le script devra :
afficher les noms des élèves, puis calculer et afficher la moyenne de
chaque élève

Voici comment se présente le fichier :

Sélectionnez

Durand 12 9 14
Lucas 8 11 4
Martin 9 12 1

95
TP 14 : solution1
#!/bin/bash

if [ "$#" -lt 1 ]; then


echo "Saisir le nom du fichier"
read -r fichier
else
fichier="$1"
fi

while read -r ligne; do


set -- "$ligne"
let moyenne=($2+$3+$4)/3
echo "L'élève $1 a pour moyenne $moyenne"
done < "$fichier"

96
TP14 : solution2
#!/bin/bash

moyenne() {
declare -i somme
for i in "$@"; do
somme+="$i"
done
echo "$((somme / ${#@}))"
}

[ -f "$1" ] && fichier="$1" || read -rep 'Entrez le nom du fichier qui contient les données : '
fichier

while read -r nom notes; do


echo -n "$nom : "
moyenne $notes
done < "$fichier"

97
98
1st SERIE D’EXERCICES

99
Q.1. Ecrire un fichier shell qui prend en parametre 2 entiers et affiche la somme. S'il n'y a pas
deux paramètres, il faut afficher un message d'erreur.

Q.2. Ecrire un script qui prend en paramètre trois entiers et qui affiche le plus grand. On affichera
un message d'erreur s'il n'y pas pas trois arguments passés sur la ligne de commande.

Q.3. Ecrire un script shell qui affichera 5,4,3,2,1 en utilisant une boucle while.

Q.4. Ecrire un script qui utilisera une instruction case pour effectuer des opérations
arithmétiques :
+ addition
- subtraction
x multiplication
/ division
Le nom du script doit être 'q4' et il s'utilisera comme suit :
$ ./q4 20 / 3
Vérifier également qu'il y a suffisamment de paramètres sur la ligne de commande.

Q.5. Ecrire un script qui listera : current date, time, username, and current directory

Q.6. Ecrire un script qui prend en paramètre un entier et affiche l'entier en ordre inverse (123 ->
321).

100
Q.7. Ecrire un script qui prend en paramètre un entier et affiche la somme des digits
qui le compose (123 -> 1+2+3 = 6).

Q.8. Quelle commande Unix vous permet de réaliser de l'arithmétique sur les réels .

Q.9. Comment calculer  5.12 + 2.5 à partir du prompt Linux ?

Q.10. Comment réaliser dans un shell un calcul sur les réels ?Par exemple, on veut
a=5.66, b=8.67, c=a+b.

Q.11. Ecrire un script qui détermine si un fichier donné en paramètre existe.

Q.12. Ecrire un script qui détrmine si l'argument $1 contient le symbole "*". Si $1 ne


contient pas le symbole "*" ajoutez le à $1, sinon affichez le message "Symbol is
not required". Le script se lance par :
$ Q12 /bin
Ici $1 est /bin, et puisque l'on n'a pas de "*" on affichera
/bin/*

101
Q.13. Ecrire un script qui affiche le contenu d'un fichier d'une ligne donnée à une
autre. Si le script s'appelle Q13 : $ Q13 5 9 myf
affiche le contenu du fichier myf de la ligne 5 a la ligne 9.
Q.14. Ecrire un script qui, au moyen de la commande getopts, affiche les options (de
la forme -c, -d, -e) passées sur la ligne de commande. Si le script s'appelle Q14
alors on pourra lancer:
Q14 -c -d -e xemacs
et le programme affichera :
-c clear the screen
-d show list of files in current working directory
-e { editor } start this { editor } if installed
et il lancera une session xemacs.
Q.15. Ecrire un script que vous insérerez dans votre fichier .bash_profile. Il affichera :
Good Morning
Good Afternoon
Good Evening , selon l'heure
Q.16. Ecrire un script qui affichera le message "Hello World", en gras et clignotant et
dans différentes couleurs en utilisant la commande echo.
Q.17. Ecrire un script qui implémente un processus en arrière plan qui affichera
continuellement l'heure courante

102
Q.18. Ecrire un script qui simule un menu permettant de réaliser les actions
suivantes :
Menu-Item Purpose Action for Menu-Item
Date/time  To see current date time Date and time must be shown using infobox
of dialog utility
Calendar must be shown using infobox of
Calendar To see current calendar dialog utility
First ask user name of directory where all
files are present, if no name of directory
given assumes current directory, then show
all files only of that directory, Files must be
Delete To delete selected file shown on screen using menus of dialog
utility, let the user select the file, then ask
the confirmation to user whether he/she
wants to delete selected file, if answer is
yes then delete the file , report  errors if
any while deleting file to user.
Exit/Stops the menu driven program i.e.
Exit To Exit this shell script
this script

103
Q.19. Ecrire un script qui vous permet d'afficher différentes informations sur
le système :
1) Currently logged user and his logname
2) Your current shell
3) Your home directory
4) Your operating system type
5) Your current path setting
6) Your current working directory
7) Show Currently logged number of users
8) About your os and version ,release number , kernel version
9) Show all available shells
10) Show mouse settings
11) Show computer cpu information like processor type, speed etc
12) Show memory information
13) Show hard disk information like size of hard-disk, cache memory,
model etc
14) File system (Mounted)
104
Q.20.Ecrire un script vous permettant de réaliser à l'écran le dessin suivant :
Ordinateur-de-Christophe-Cerin:~ cerin$ /bin/bash Q20.sh
Enter Number between (5 to 9) : 9
.
..
...
....
.....
......
.......
........
.........
.........
........
.......
......
.....
....
...
..
.
Ordinateur-de-Christophe-Cerin:~ cerin$ 105
Q.21. Ecrire un script qui converti un fichier de majuscule à minuscule et vice et versa selon ce que l'on passe
sur la ligne de commande.
Q.22 Editer un fichier pour qu’il contienne le texte suivant :
case $# in
0) variable=`pwd`;;
1) variable=$1 ;;
*) echo "Erreur de syntaxe" ; exit;;
esac
a) Exécuter le code pour faire apparaître le message d’erreur
b) Modifier le code en ajoutant du texte après le esac pour que le programme affiche la valeur de variable
si elle a été positionnée par `pwd`uniquement.
Q-23 La commande set sert a affecter les variables $0, $1 alors que la commande shift permet de décaler sur
la gauche les valeurs des paramètres positionnels. Voir l’exemple suivant :
$ set ab cd
$ echo $1
ab
$ shift
$ echo $1
cd
$ shift
$ echo $1
$
Écrire un script permettant d'afficher à l'écran le contenu d'une série de fichiers dont les noms sont passés
en paramètres, et n'utilisant pas de boucle for. Le message <nom fichier> inaccessible sera affiché si le
fichier <nom fichier> est inexistant ou ne peut être lu. 106
Q-24 Écrire un script (en utilisant set, par exemple) permettant de convertir une date, renvoyée
par la commande date, sous le format suivant (en français) :
Lundi 16 Decembre 1996 15:31:37
Note : on peut se servir de set et shift mais on ne peut pas faire quelque chose du genre :
$ date "+DATE: %m/%d/%y%nTIME: %H:%M:%S"
DATE: 10/03/05
TIME: 09:53:14
Q-25 Tapez sous le prompt de l’interpréteur bash les commandes suivantes et observez les
résultats (certains peuvent être différents sur votre système, en particulier pour la
commande pwd). En fait, les () permettent d’ouvrir et de fermer un nouveau shell.
Expliquer ce qui s’est passé.
$ pwd
/users/linfg/linfg0
$ a=1
$ ( echo $a ; a=2 ; echo $a ; cd /usr/include ; pwd )
1
2
/usr/include
$ echo $a
1
$ pwd
/users/linfg/linfg0
$ 107
Q-26 Taper le code suivant et observer les valeurs de a. Si vous n’obtenez pas 1 pour le premier
affichage, que faut-il faire ? (voir la commande export)
$ a=1
$ bash
$ echo $a ; a=2 ; echo $a ; cd /usr/include ; pwd
$ exit

Q-27 Modifier le moins possible le code suivant pour faire apparaitre à l'écran que le chien et le
chat sont des « animaux domestiques qui vivent à la maison » :
echo -n Enter the name of an animal:
read ANIMAL
echo -n The $ANIMAL has

Q-28 La commande shell select permet d’élaborer facilement des menus. Tapez le code suivant
puis entrer un entier :
select fname in *;
do
echo you picked $fname \($REPLY\)
break;
done
Inspirez vous de ce texte pour ne lister que les fichiers d’extension txt ou doc. Vous pouvez
utiliser l’expansion avec {}.
108
Q-29 Vous lancer la commande ps et vous la redirigez dans un fichier. Ecrire un script permettant d'afficher
uniquement les processus triés par ordre alphabétique. Vous pouvez utiliser sort, uniq, cut... Modifiez votre
script pour afficher le nom des processus ainsi que le nombre d'occurrences de ce processus.
Q-30 Créer un script test-fichier, qui précisera le type du fichier passé en paramètre, ses permissions d'accès
pour l'utilisateur. Exemple de résultats :
Le fichier /etc est un répertoire
"/etc" est accessible par root en lecture écriture exécution
Le fichier /etc/smb.conf est un fichier ordinaire qui n'est pas vide
"/etc/smb.conf" est accessible par jean en lecture.

Q-31 Afficher le contenu d'un répertoire : Écrire un script bash listedir.sh permettant d'afficher le contenu d'un
répertoire en séparant les fichiers et les (sous)répertoires. Exemple d'utilisation :
$ ./listdir.sh
affichera :
-------------- Fichiers dans /etc/rc.d --------------------
rc
rc.local
rc.sysinit
-------------- Repertoires dans /etc/rc.d --------------------
init.d
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d 109
Q-32 Lister les utilisateurs
Écrire un script bash affichant la liste des noms de login des utilisateurs définis dans
/etc/passwd ayant un UID supérieur à 500.
Indication : for in $(cat /etc/passwd) permet de parcourir les lignes du dit fichier.

Q-33 lecture au clavier


La commande bash read permet de lire une chaîne au clavier et de l'affecter à une variable.
exemple :
echo -n "Entrer votre nom: "
read nom
echo "Votre nom est $nom"
La commande file affiche des informations sur le contenu d'un fichier (elle applique des
règles basées sur l'examen rapide du contenu du fichier).
Les fichiers de texte peuvent être affichés page par page avec la commande more.

1- Tester ces trois commandes;

2- Écrire un script qui propose à l'utilisateur de visualiser page par page chaque fichier
texte du répertoire spécifié en argument. Le script affichera pour chaque fichier texte (et
seulement ceux là) la question "voulez vous visualiser le fichier machintruc ?". En cas de
réponse positive, il lancera more, avant de passer à l'examen du fichier suivant.

110
Q34 Gestion des notes

N1) Écrire un script qui demande à l'utilisateur de saisir une note et qui affiche un message
en fonction de cette note :
"très bien" si la note est entre 16 et 20
"bien" lorsqu'elle est entre 14 et 16
"assez bien" si la note est entre 12 et 14
"moyen" si la note est entre 10 et 12
"insuffisant" si la note est inférieur à 10

N2) Reprenez l'exercice 1 et faites en sorte que le programme se répète tant que
l'utilisateur n'ai pas saisi une note négative ou q (pour quitter). Le script doit calculer le
nombre de notes saisies et en faire la moyenne tout à la fin.

N3) Reprenez uniquement le code de l'exercice 1. La note peut cette fois être donnée en
paramètre ou bien être saisie si elle n'a pas été trouvée en paramètre. La comparaison de la
note devra être faite dans une fonction "appreciation".

111
NIVEAU SUPERIEUR

Q0- Un fichier contient des entiers au format binaire, un par ligne. Donner une commande sed qui permet
d'afficher les entiers qui commencent et se terminent par 1 avec au milieu 2 à 4 zéro:

Q1- Ecrire un programme shell qui prend en paramètre un exécutable, qui va retrouver tous les numéros de
processus et les détruire. Il s’agit de simuler la commande killall. Vous pouvez vous inspirer du code
suivant :

#!/bin/bash
TITI="`echo $1`"
for i in `ps -hu | cut -c 8-14 `
do
TOTO=`ps -h $i | cut -c 22- | grep -G $TITI | cut -f 1 -d " "`
NUM=`echo $TOTO | wc -c `
if test $NUM -ne 1; then
ps -h $i
echo "Detruction du PID $NUM"
# kill –9 $NUM
fi
done

112
2nd SERIE D’EXERCICES

113
Exercice 1
Créer un script shell nommé "change" qui affichera la date de dernière
modification d'un fichier puis la modifiera avec l'heure actuelle et enfin réaffichera
la date de dernière modification du fichier.
Cette procédure acceptera 1 paramètre qui sera le nom du fichier.
Lorsque vous exécuterez "change mon_fic", le 8 octobre à 15 heures 12 vous
obtiendrez le résultat:
avant : -r--r--r-- 1 user group 40 Fev 3 2001  mon_fic
après : -r--r--r-- 1 user group 40 Oct 8 15:12 mon_fic

Exercice 1 change.bash
1 AVANT=$(ls -l $1)
2 touch $1
3 APRES=$(ls -l $1)
4 echo "Avant : "$AVANT
5 echo "Apres : "$APRES

114
Exercice 2
Créer un script shell nommé "nombreJours" qui affichera le nombre de jours du
mois courant.
"nombreJours" affichera pour février 2007 le message "28 jours en février 2007" 

Exercice 2 nombreJours.bash ANNEE=$(date +"%Y")


case $MOIS in
MOIS=$(date +"%m") 01|03|05|07|08|10|12)
case $MOIS in echo "31 jours en "$NOM" "$ANNEE;;
01) NOM="janvier";; 04|06|09|11)
02) NOM="fevrier";; echo "30 jours en "$NOM" "$ANNEE;;
02)
03) NOM="mars";; BISSEXTILITE=$(expr $ANNEE % 4)
04) NOM="avril";; if [ $BISSEXTILITE != 0 ]
05) NOM="mai";; then
06) NOM="juin";; echo "28 jours en "$NOM" "$ANNEE
07) NOM="juillet";; else
BISSEXTILITE=$(expr $ANNEE % 100)
08) NOM="aout";;
if [ $BISSEXTILITE != 0 ]
09) NOM="septembre";; then
10) NOM="octobre";; echo "29 jours en "$NOM" "*ANNEE
11) NOM="novembre";; else
12) NOM="decembre";; BISSEXTILITE=$(expr $ANNEE % 400)
if [ $BISSEXTILITE != 0 ]
esac then
echo "28 jours en "$NOM" "$ANNEE
else
echo "29 jours en "$NOM" "$ANNEE
fi
fi
fi;;
esac 115
Exercice 3
Créer un script shell réalisant la création d'un répertoire "Exo3" contenant 10
fichiers nommés "Un" à "Dix". Chaque fichier contient une seule ligne:
"Un" contient "Première ligne"
"Deux" contient "Deuxième ligne"
...
"Dix" contient "Dixième ligne"
Vérifier que le répertoire à créer n'existe pas déjà auquel cas il ne sera pas recréé
mais les fichiers si. Exercice 3 / script3.bash

1 test -e Exo3
2 if [ $? != 0 ]
3 then
4 mkdir Exo3
5 fi
6 echo "Premiere ligne" >Exo3/Un
7 echo "Deuxieme ligne" >Exo3/Deux
8 echo "Troisieme ligne" >Exo3/Trois
9 echo "Quatrieme ligne" >Exo3/Quatre
10 echo "Cinquieme ligne" >Exo3/Cinq
11 echo "Sixieme ligne" >Exo3/Six
12 echo "Septieme ligne" >Exo3/Sept
13 echo "Huitieme ligne" >Exo3/Huit
14 echo "Neuvieme ligne" >Exo3/Neuf
15 echo "Dixieme ligne" >Exo3/Dix

116
Exercice 4
Créer un script shell qui réalise les opérations suivantes:
Création sous votre répertoire "TP2" d'un sous répertoire nommé
"annéemoisjour" (20070202 pour le 2 février 2007).
Copie des fichiers de "Exo3" sous ce répertoire puis effacement de ces mêmes
fichiers de "Exo3".
Création de deux fichiers sous le répertoire d'accueil (HOME) de la personne qui a
lancé le shell:
un fichier nommé "Gros_fichier.numero_du_shell" dans lequel se trouvera le
contenu concaténé des fichiers traités
un fichier nommé "Nom_du_script.numero_du_shell" dans lequel se
trouvera le nom des fichiers traités.
Vérifier que le répertoire à créer n'existe pas déjà.
Exercice 4 : script4.bash

1 REP=$(date +"%Y%m%d")
2 test -e $REP
3 if [ $? != 0 ]
4 then
5 mkdir $REP
6 fi
7 cp Exo3/* $REP
8 rm Exo3/*
9 for file in $REP/*
10 do
11 cat $file >> ~/Gros_fichier.$
12 echo $file >> ~/$0.$
13 done
14 117
Exercice 5
Créer un script permettant d'afficher la liste des fichiers du répertoire /etc
accessibles en lecture.
Créer un script permettant d'afficher la liste des fichiers du répertoire /etc
accessibles en écriture.
Exercice 5 : script5a.bash

1 for FILE in /etc/*


2 do
3 if test -r $FILE
4 then
5 echo $FILE
6 fi
7 done
8

script5b.bash

1 for FILE in /etc/*


2 do
3 if test -w $FILE
4 then
5 echo $FILE
6 fi
7 done
8 118
Exercice 6
Créer un script nommé "table" permettant d'afficher des tables de multiplication.
"table 5 10" aura pour résultat l'affichage:
0x5=0
1x5=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

Exercice 6 / table.bash

1 for V in $(seq 0 $2)


2 do
3 echo $V" x "$1" = "$(expr $V "*" $1 )
4 done
5

119
SHELL PROGRAMMING
BEST PRACTICES

120
SHELL PROGRAMMING
BEST PRACTICES
http://ineumann.developpez.com/tutoriels/linu
x/bash-bonnes-pratiques/

121
PRATIQUE – GRP(99.MIL)
• Ecrire un script qui renomme le contenu de tous les fichiers.
En précédant le nom d’origine par le nom d’utilisateur.
#!/bin/bash
CONTENU=`ls`
for i in $CONTENU
do
if [ $i != $0 ]; then
mv $i `whoami`-$i
fi
done

122
PRATIQUE – GRP(99.MIL)
• Nous disposons d’un fichier texte qui contient des noms, on se
propose de créer tous les dossiers qui portent les noms qui
figurent dans le fichier précédant
$ cat filezz #!/bin/bash
ALGER
CONTENU=`cat filezz`
TIZI
BOUIRA
for i in $CONTENU
BBA do
ORAN mkdir $i
TLEMCEN done
SETIF

123

Vous aimerez peut-être aussi