1. Prof. C. EL AMRANI Système d’Exploitation UNIX
1
Le Shell
L’interpréteur de commandes shell est un programme qui gère l’interface utilisateur-système en
faisant exécuter les commandes que l’utilisateur entre au clavier ou qu’il regroupe dans un
fichier dit script shell. Plusieurs syntaxes (shells) existent pour exprimer ces commandes. Il y
en a en gros 2 familles : les Bourne shells (sh, ksh, bash) dérivant du premier interpréteur de
commande sh écrit par Bourne, et les C-shells dérivant d’interpréteurs de commandes
s’inspirant de la syntaxe du C (csh, tcsh). Le shell est un processus comme les autres en Unix,
ce qui explique qu’on peut le changer ou le réécrire. Lors du login, l’utilisateur est connecté
avec un répertoire et un shell définis lors de la création de son compte [le shell peut être changé
à l’aide de la commande chsh].
Dans la suite du cours, on étudiera le shell bash (compatible sh). Le bash permet une édition
facile des lignes de commandes [on retrouve les commandes précédentes avec les touches
flèches du clavier], la gestion d’un historique des commandes [commande history permet de
lister les commandes tapées précédemment, on reexécute une de ces commande en donnant son
numéro précédé de !].
Souvent sh et bash sont rigoureusement le même produit. sh est un lien symbolique vers bash :
ls –l /bin/sh
/bin/sh -> /bin/bash
1. Les variables d’environnement
Les variables d’environnement sont des variables contenant des chaînes de caractère. Il n’y a
pas de déclarations de types comme en C. Ces variables contiennent des informations
utilisables dans différents programmes.
printenv donne la liste des variables d’environnement. Le shell utilise des variables
d’environnement définies dans les fichiers d’initialisation exécutés lors du login. Comme
exemple des variables d’environnement des Bournes shells on trouve :
PWD : contient le répertoire courant
HOME : contient le répertoire d’acceuil
PATH : contient la liste des répertoires où l’interpréteur recherche les fichiers correspondant
aux commandes
TERM indique le type du terminal
SHELL indique le nom du shell utilisé
Echo $VARIABLE permet d’obtenir la valeur de VARAIBLE
Exemple :
echo $PATH
/usr/local/bin : /bin: /usr/bin: /home/etudiant/bin
On peut modifier la valeur de PATH on y ajoutant un nouveau répertoire :
PATH="$PATH : /home/etudiant/ProgC"
2. Le Shell
Prof. C. EL AMRANI
2
2. Les variables de l’utilisateur (variables du shell)
L’utilisateur peut définir ses propres variables. Il ne doit pas y avoir d’espace autour du signe =.
Exemple :
A=$HOME/ProgC
echo $A
/home/compte1/ProgC
cd $A (on se met dans le répertoire /home/etudiant/ProgC)
Les variables sont locales au processus. La variable A ne sera pas donc connue dans les
programmes exécutés par l’interpréteur de commandes. Pour qu’une variable soit connue dans
les processus fils d’un processus, il faut la déclarer export. Ces variables exportées peuvent être
testées dans un programme C ou dans un script shell.
Exemple :
export A=/home/etudiant/ProgC
3. Résultats d’une commande
Habituellement, une commande fournit un résultat indiquant si l’exécution s’est bien passée,
par convention 0 pour vrai ; différent de 0 pour faux. Ce résultat peut être testé en utilisant la
variable ? référencée par $?. Ce résultat est fourni par exit dans un script shell.
Exemple :
rm temp.txt (temp.txt n’existe pas)
echo $?
1
4. Les expressions arithmétiques
expr effectue des opérations arithmétiques avec des variables shell. Les opérateurs classiques
sont utilisables : + - * / %. L’opérateur * doit être protégé et écrit * car il fait partie des
caractères génériques.
Exemple :
N=2
expr $N + 1 (résultat : 3)
expr 3* 2 (résultat : 6)
En Korn shell et en bash, on peut écrire plus simplement des expressions arithmétiques en
déclarant un type pour les variables (-i pour les entiers).
Exemple :
typeset –i a=2
typeset –i b=3
typeset –i c=$a*$b
echo $c (résultat : 5)
On peut aussi utiliser une structure ((…)) pour manipuler des variables de type entier.
Exemple :
3. Le Shell
Prof. C. EL AMRANI
3
((a=20))
echo $((a*=5))
(résultat : 100)
((a=20))
((a*=5))
echo $a
(résultat : 100)
5. Les scripts Shell
5.1. Principe
Un script est un ensemble de commandes répertoriées dans un fichier et ayant éventuellement
des paramètres. Le nom de la commande correspond au nom du fichier. Les variables suivantes
sont prédéfinies dans les scripts Shell :
*
Liste des paramètres d’appel de la commande ($*)
#
Nombre de paramètres lors de l’appel de la commande ($#)
$
Numéro du processus courant ($$)
! Numéro du dernier processus en arrière plan ($ !)
? Valeur du code de retour de la dernière commande exécutée ($?)
Exemple :
echo $$ (résultat 1870)
Exemple de script :
Soit le script : script1
#!/bin/bash chemin d’accès du shell bash
clear efface l’écran
echo -n "Repertoire courant: "; pwd affiche le répertoire courant
date +"%d/%m/%Y a %Hh%M" affiche la date
echo -n "Nmbre de fichiers: "; ls | wc –l affiche le nombre de fichiers dans le répertoire
courant, « n » pour afficher sur la même ligne
Il faut rendre le fichier exécutable avec :
chmod u+x script1
exécuter avec : ./script1
si on ajoute dans PATH le répertoire ou se trouve script1, ce dernier pourra être lancé de
n’importe quel répertoire : PATH= "$PATH:$HOME/scripts" (sachant que script1 se trouve
4. Le Shell
Prof. C. EL AMRANI
4
dans le répertoire /scripts)
Exécution de script1 :
15/03/2004 a 10h15
Repertoire courant: /home/compte5/scripts
Nombre de fichiers: 1
On peut ajouter des paramètres après la commande script :
script1 programmes
#!/bin/bash
clear
echo "Repertoire courant: $1"
date +"%d/%m/%Y a %Hh%M"
echo -n "Nmbre de fichiers: "; ls | wc -l
Exécution de script2 :
15/03/2004 a 10h15
Repertoire courant: programmes
Nombre de fichiers: 1
5.2. Enchaînement des commandes en Shell
Dans un script Shell on retrouve les structures classiques des langages de programmation :
Alternatives
Choix multiples
Boucles
5.2.1. Alternatives, opérateurs && et ||
Syntaxe :
if liste_de_commandes ; then
liste_de_commandes
fi
La commande test permet d’exprimer des conditions suivant différents critères ; elle est
souvent écrite sous sa deuxième forme ([ ]) dans les scripts Shell (espace obligatoire après [ et
avant ]). Les expressions les plus utilisées sont :
-d nom vrai si le répertoire nom existe
-f nom vrai si le fichier nom existe
-s nom vrai si le fichier nom existe et est non vide
-r nom vrai si le fichier nom existe et est accessible en lecture
-w nom vrai si le fichier nom existe et est accessible en écriture
-x nom vrai si le fichier nom existe et est exécutable
-z chaîne vrai si la chaîne de caractère chaîne est vide
-n chaîne vrai si la chaîne de caractère chaîne est non vide
5. Le Shell
Prof. C. EL AMRANI
5
c1 = c2 vrai si les chaînes de caractères c1 et c2 sont identiques
c1 != c2 vrai si les chaînes de caractères c1 et c2 sont différentes
n1 –eq n2 vrai si les entiers n1 et n2 sont égaux
Opérateurs relationnels Opérateurs logiques
-ne différent
-lt inférieur
-le inférieur ou égal
-gt supérieur
-ge supérieur ou égal
-a ET logique
-o OU logique
! NON logique
Exemple 1 :
Le script altern1 comporte un paramètre $1 indiquant le fichier dont on veut connaître
l’existence ;
altern1 vérifie si le fichier $1 existe ou pas
# !/bin/bash
if test –f $1 ; then ou encore : if [ -f $1 ] ; then …
echo "Le fichier $1 existe"
else
echo "Le fichier $1 n’existe pas" ; exit 1 exit valeur termine la commande et
retourne valeur
fi
execution :
./test fichier1
Exécution :
altern1 lettre.txt le fichier lettre.txt n’existe pas
lettre.txt n’existe pas
Exemple2 : altern2
# !/bin/bash
if [ -f $1 ] ; then
echo "Le fichier $1 existe"
elif [ -d $1 ] ; then
echo "$1 est un répertoire"
else
echo "Le fichier $1 n’existe pas " ;
6. Le Shell
Prof. C. EL AMRANI
6
exit 1
fi
Exemple3 : altern3
# !/bin/sh
if [ $# -ne 1 ]; then
echo " Un seul paramètre est autorisé" ; exit 1
fi
le script altern3 teste si le nombre de paramètres de la commande vaut 1
Exécution :
altern3 aa
echo $?
0
altern3 aa bb
Un seul paramètre est autorisé
echo $?
1
Exemple4 : Utilisation de &&
com1 && com2 : si la commande com1 est vrai, com2 est exécutée. Si com1 est fausse com2
n’est pas exécutée
# !/bin/sh
[ ! –d $1 ] && echo "Répertoire $1 inconnu"
si $1 n’est pas un répertoire on affiche le message
Exemple5 : Utilisation de | |
com1 | | com2 : com2 est exécutée si com1 échoue
# !/bin/bash
[ –d $1 ] | | echo "Répertoire $1 inconnu"
si $1 n’est pas un répertoire on affiche le message
5.2.2. Choix multiples
L’instruction case est très puissante et très commode pour effectuer un choix multiple dans un
fichier de commandes :
case chaîne in
cas1) commnade_1 ;;
cas2) commande_2 ;;
esac
7. Le Shell
Prof. C. EL AMRANI
7
cas1, cas2,.. sont des chaînes de caractère
Exemple1: choix1
# !/bin/bash
case $# in
0) echo "$0 sans argument" ;;
1) echo "$0 possede un argument" ;;
*) echo "$0 possède plus de deux arguments" ;;
esac
Exécution :
choix1 aa bb cc
choix1 possède plus de deux arguments
Exemple2: choix2
# !/bin/bash
case $1 in
aa) echo "$0 possède le paramètre aa" ;;
bb) echo "$0 possède le paramètre bb" ;;
*) echo "$0 possède un paramètre différent de aa et bb " ;;
esac
Exécution :
./choix2 bb
choix2 possède le paramètre bb
5.2.3. Itération bornée for
La boucle for admet trois syntaxes :
Forme 1 :
for variable in liste_de_chaînes ; do
liste_de_commandes
done
les valeurs de variable sont les chaînes de liste_de_chaînes
Exemple1 : boucle1
#!/bin/bash
for i in 2017 2018 2020 ;
do
echo –e "======calendrier $inn"
cal $i
done
Exemple2 : boucle2
#!/bin/sh
#écrit les paramètres de la ligne de commande
8. Le Shell
Prof. C. EL AMRANI
8
for i in $*;
do
echo $i #traite le i eme paramètre
done
Exécution :
$ ./boucle2 aa bb cc
aa
bb
cc
Forme 2 :
for variable ;
do
liste_de_commandes
done
variable prend les valeurs dans la liste des paramètres du script.
Exemple3 : boucle3
# !/bin/bash
for i;
do
echo $i
done
Exécution :
$ ./boucle3 aa bb
aa
bb
Forme 3 :
for variable in * ;
do
liste_de_commandes
done
La liste des fichiers du répertoire constitue les valeurs prises par variable
Exemple 4 : boucle4
# !/bin/bash
for i in *;
do
echo $i
done
9. Le Shell
Prof. C. EL AMRANI
9
Exécution :
$ ./boucle4
liste tous les fichiers du répertoire courant.
5.2.4. Itérations non bornées : while et until
Les syntaxes sont :
while liste_de_commandes1 ;
do
liste_de_commandes2
done
liste_de_commandes2 est exécutée tant que liste_de_commandes1 retourne un code nul (la
condition est vraie).
until liste_de_commandes1 ;
do
liste_de_commandes2
done
liste_de_commandes2 sont exécutées jusqu’à ce que liste_de_commandes1 retourne un code
nul (la condition est vraie)
Exemple1 : iter1
#!/bin/bash
while echo -n "votre choix (1, 2, 3 ou 4)? ";
read choix;
[ $choix -lt 1 -o $choix -gt 4 ];
do
echo -e "nUne valeur entre 1 et 4 SVP!"
done
echo "votre choix : $choix"
read : lit une ligne sur l’entrée standard
-o : OR
Exemple 2 : iter2
#!/bin/bash
choix=0
until [ $choix -ge 1 -a $choix -le 4 ];
do
echo -n "votre choix (1, 2, 3, 4)? ";
read choix;
done
echo "votre choix : $choix"
10. Le Shell
Prof. C. EL AMRANI
10
-a : AND
5.2.5. La commande shift
L’idée de la commande shift est de traiter le premier paramètre $1 et de décaler tous les
paramètres vers la gauche. $1 disparaît, $2 devient $1, etc. jusqu’à ce qu’il n’y ait plus de
paramètre.
Exemple : shift1
#!/bin/bash
while [ $# -ne 0 ];
do
echo "parametre $1"
shift
done
Exécution :
shift1 aa bb
parametre aa
parametre bb
5.2.6. Les fonctions
Exemple
#!/bin/bash
# déclaration et definition d une fonction
Fonction1()
{ var1="je suis la fonction"
echo "$var1"
echo "Nombres de paramètres : $#"
echo $1
echo $2
}
# appel de ma fonction
Fonction1 hello world