445 lines
15 KiB
HTML
445 lines
15 KiB
HTML
|
<?xml version="1.0" encoding="UTF-8"?>
|
|||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|||
|
<head>
|
|||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|||
|
<title>Tests</title>
|
|||
|
<link rel="stylesheet" href="../../tuteurs.css" type="text/css" />
|
|||
|
</head>
|
|||
|
<body>
|
|||
|
<div class="navigation">
|
|||
|
<h1>Tuteurs informatique<br /><a href="../../meta/contact.html">Nous contacter</a></h1>
|
|||
|
<hr />
|
|||
|
<ul class="menu">
|
|||
|
<li>
|
|||
|
<a href="../../meta/charte_graphique.html">Utiliser ce site</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="../../actualite.html">Actu et stages</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="../../docs/">Docs à imprimer</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="../../meta/plan_site.html">Plan du site</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="../../search.html">Rechercher</a>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
<hr />
|
|||
|
<ul class="arbre">
|
|||
|
<li>
|
|||
|
<a href="../../">Les tuteurs</a>
|
|||
|
<ul class="arbre">
|
|||
|
<li>
|
|||
|
<a href="../">Unix</a>
|
|||
|
<ul class="arbre">
|
|||
|
<li>
|
|||
|
<a href="./">Shell</a>
|
|||
|
<ul class="arbre">
|
|||
|
<li>
|
|||
|
<a href="boucle.html">Boucles</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="commande.html">Commandes</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="entreesortie.html">Entrée/sortie</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="fonction.html">Fonctions</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="presentation.html">Présentation</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="script.html">Scripts</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="test.html" class="actuel">Tests</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="variable.html">Variables</a>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
<hr />
|
|||
|
<ul class="menu">
|
|||
|
<li>
|
|||
|
<a href="http://www.eleves.ens.fr/">Serveur des élèves</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="http://www.ens.fr/">ENS</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="http://www.spi.ens.fr/">SPI</a>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
</div>
|
|||
|
<div class="corps">
|
|||
|
<h1>Tests et calcul arithmétique</h1>
|
|||
|
<div class="sommaire">
|
|||
|
<ul>
|
|||
|
<li>
|
|||
|
<a href="#s1">Qu'est-ce qu'un test ?</a>
|
|||
|
<ul>
|
|||
|
<li>
|
|||
|
<a href="#s1_1">Une condition</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="#s1_2">Code de retour d'un test</a>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="#s2">Les opérateurs</a>
|
|||
|
<ul>
|
|||
|
<li>
|
|||
|
<a href="#s2_1">Opérateurs logiques</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="#s2_2">Opérateurs arithmétiques</a>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<a href="#s2_3">Opérateurs sur les fichiers</a>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
</div>
|
|||
|
<h2>
|
|||
|
<a name="s1" id="s1">Qu'est-ce qu'un test ?</a>
|
|||
|
</h2>
|
|||
|
<p><strong>Un test est une opération dont le but est d'évaluer la valeur
|
|||
|
d'une expression</strong>. Cette expression peut être simplement
|
|||
|
l'<em>existence</em> de quelque chose (par exemple, d'un fichier, ou
|
|||
|
bien d'une variable), ou ce peut être une <em>proposition</em>.</p>
|
|||
|
<p>Concrètement, cela veut dire qu'<strong>un programme n'est pas limité
|
|||
|
à la possibilité de donner des ordres : il peut aussi poser des
|
|||
|
questions</strong>, et agir comme vous le décidez en fonction des
|
|||
|
réponses apportées aux questions.</p>
|
|||
|
<p>Posons par exemple le principe suivant : « Si Dieu n'existe
|
|||
|
pas, alors tout est permis. » Nous allons ensuite tester si Dieu
|
|||
|
existe, et s'il n'existe pas, nous saurons que tout est permis. Autre
|
|||
|
exemple : posons que « si le train passe sous le tunnel avant
|
|||
|
que j'aie compté jusqu'à dix, alors Manek est vivant. » Je vais
|
|||
|
donc tester si le train passe sous le tunnel avant que j'aie compté
|
|||
|
jusqu'à dix, et si c'est le cas, alors c'est que Manek est vivant. C'est
|
|||
|
aussi simple que cela.</p>
|
|||
|
<h3>
|
|||
|
<a name="s1_1" id="s1_1">Une condition</a>
|
|||
|
</h3>
|
|||
|
<p>Le shell propose deux principales façons de réaliser un test ;
|
|||
|
ces deux méthodes sont équivalentes :</p>
|
|||
|
<ul>
|
|||
|
<li>
|
|||
|
<code>test <em>expression</em></code>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<code>[ <em>expression</em> ]</code>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
<p>
|
|||
|
Les deux commandes suivantes reviennent donc au même :</p>
|
|||
|
<pre><span class="prompt">clipper ~ $</span> <strong>test -f foo</strong> || echo "Le fichier foo n'existe pas."
|
|||
|
Le fichier foo n'existe pas.
|
|||
|
<span class="prompt">clipper ~ $</span> <strong>[ -f foo ]</strong> || echo "Le fichier foo n'existe pas."
|
|||
|
Le fichier foo n'existe pas.
|
|||
|
</pre>
|
|||
|
<h3>
|
|||
|
<a name="s1_2" id="s1_2">Code de retour d'un test</a>
|
|||
|
</h3>
|
|||
|
<p>Un test renvoie un <em>code de retour</em>. <strong>Un code de retour
|
|||
|
est un nombre (0 ou autre), qui correspond à une réponse de
|
|||
|
type « vrai » ou « faux »</strong>. C'est ce code de
|
|||
|
retour qui permet la manipulation des tests dans des structures de
|
|||
|
contrôle comme <code>if</code>, etc. </p>
|
|||
|
<p>
|
|||
|
Le code de retour 0 correspond à la réponse
|
|||
|
« vrai ». Pour répondre « faux », le programme
|
|||
|
répond... autre chose (ce peut être 1, 2, -1 ou autre).
|
|||
|
</p>
|
|||
|
<p>Par exemple, un conducteur de voiture utilise le programme
|
|||
|
suivant :</p>
|
|||
|
<pre>
|
|||
|
while [[ "$couleur_du_feu" != "vert" ]]
|
|||
|
do attendre
|
|||
|
done
|
|||
|
|
|||
|
démarrer
|
|||
|
</pre>
|
|||
|
<h2>
|
|||
|
<a name="s2" id="s2">Les opérateurs</a>
|
|||
|
</h2>
|
|||
|
<h3>
|
|||
|
<a name="s2_1" id="s2_1">Opérateurs logiques</a>
|
|||
|
</h3>
|
|||
|
<h4>Non : l'opérateur « <code>!</code> »</h4>
|
|||
|
<p><strong>L'opérateur logique « non » inverse le code de
|
|||
|
retour d'une commande</strong>, c'est-à-dire renvoie vrai si elle
|
|||
|
renvoie faux, et vice versa. </p>
|
|||
|
<p>On utilise cet opérateur en précédant une condition d'un point
|
|||
|
d'exclamation (« ! »). </p>
|
|||
|
<h5>Comparaison de plusieurs combinaisons d'opérateurs</h5>
|
|||
|
<p>Pour illustrer l'usage de cet opérateur, voici quatre cas de figure
|
|||
|
différents :</p>
|
|||
|
<pre>
|
|||
|
# Premier cas
|
|||
|
[ <strong>-f</strong> foo ] <strong>&&</strong> echo "Le fichier foo existe."
|
|||
|
</pre>
|
|||
|
<p class="continue">Dans l'exemple précédent, le shell teste si le
|
|||
|
fichier <code>foo</code> existe. Comme il n'existe pas, le code de
|
|||
|
retour de ce test est faux (un nombre différent de 0). Or, l'opérateur
|
|||
|
« && » n'exécute ce qui suit que si le code de retour est vrai
|
|||
|
(i.e. 0) car si <code>a</code> est faux
|
|||
|
alors <code>a&&b</code> sera aussi nécessairement faux. Comme
|
|||
|
ce n'est pas le cas, les commandes ne sont pas exécutées. </p>
|
|||
|
<pre>
|
|||
|
# Deuxième cas
|
|||
|
[ <strong>-f</strong> foo ] <strong>||</strong> echo "Le fichier foo n'existe pas."
|
|||
|
Le fichier foo n'existe pas.
|
|||
|
</pre>
|
|||
|
<p class="continue">Dans cet exemple, l'opérateur n'est plus
|
|||
|
« && » mais « || ». Les commandes ne s'exécutent que si le
|
|||
|
code de retour vaut faux (i.e. différent de 0); comme c'est le cas,
|
|||
|
elles sont exécutées. En effet si <code>a</code> est vrai
|
|||
|
alors <code>a||b</code> sera aussi nécessairement vrai, ce n'est pas la
|
|||
|
peine de l'exécuter.</p>
|
|||
|
<pre>
|
|||
|
# Troisième cas
|
|||
|
[ <strong>! -f</strong> foo ] <strong>&&</strong> echo "Le fichier foo n'existe pas."
|
|||
|
Le fichier foo n'existe pas.
|
|||
|
</pre>
|
|||
|
<p class="continue">Ici, l'opérateur est de nouveau « && » ;
|
|||
|
mais contrairement aux deux exemples précédents, le test n'est
|
|||
|
plus <code>[ -f foo ]</code> mais <code>[ ! -f foo ]</code>. Par
|
|||
|
conséquent, le code de retour est vrai (i.e. 0), et les commandes sont
|
|||
|
exécutées.</p>
|
|||
|
<pre>
|
|||
|
# Quatrième cas
|
|||
|
[ <strong>! -f</strong> foo ] <strong>||</strong> echo "Le fichier foo existe."
|
|||
|
</pre>
|
|||
|
<p class="continue">Voici la dernière combinaison possible. Le code de
|
|||
|
retour est vrai (i.e 0), mais il fallait faux (e.g. 1) pour que les
|
|||
|
commandes soient exécutées. </p>
|
|||
|
<p>Ces quatre exemples correspondent aux énoncés suivants :</p>
|
|||
|
<ul>
|
|||
|
<li><em>s'il est vrai que <code>foo</code> existe</em>, alors il faut
|
|||
|
écrire : « Le fichier foo existe. ».</li>
|
|||
|
<li><em>s'il n'est pas vrai que <code>foo</code> existe</em>, alors il
|
|||
|
faut écrire : « Le fichier foo n'existe pas. ».</li>
|
|||
|
<li><em>s'il est vrai que <code>foo</code> n'existe pas</em>, alors il
|
|||
|
faut écrire : « Le fichier foo n'existe pas. ».</li>
|
|||
|
<li><em>s'il n'est pas vrai que <code>foo</code> n'existe pas</em>,
|
|||
|
alors il faut écrire : « Le fichier foo existe. ».</li>
|
|||
|
</ul>
|
|||
|
<h5>Reformulation avec <code>if</code></h5>
|
|||
|
<p>Dans un script, outre la formulation précédente, on pourra
|
|||
|
écrire :</p>
|
|||
|
<pre>
|
|||
|
# Premier cas
|
|||
|
if [ -f foo ]
|
|||
|
then echo "Le fichier foo existe."
|
|||
|
else continue
|
|||
|
fi
|
|||
|
|
|||
|
# Deuxième cas
|
|||
|
if [ -f foo ]
|
|||
|
then continue
|
|||
|
else echo "Le fichier foo n'existe pas."
|
|||
|
fi
|
|||
|
|
|||
|
# Troisième cas
|
|||
|
if [ ! -f foo ]
|
|||
|
then echo "Le fichier foo n'existe pas."
|
|||
|
else continue
|
|||
|
fi
|
|||
|
|
|||
|
# Quatrième cas
|
|||
|
if [ ! -f foo ]
|
|||
|
then continue
|
|||
|
else echo "Le fichier foo existe."
|
|||
|
fi
|
|||
|
</pre>
|
|||
|
<h4>Et : l'opérateur « <code>-a</code> »</h4>
|
|||
|
<p>L'opérateur « et » renvoie 0 (vrai) si et seulement si les
|
|||
|
différentes conditions sont toutes réalisées ; si au moins l'une
|
|||
|
d'entre elles ne l'est pas, le code de retour est 1 (faux). On note
|
|||
|
cet opérateur en insérant « -a » entre les différentes
|
|||
|
conditions. Exemples : </p>
|
|||
|
<pre>
|
|||
|
touch foo # donc foo existe
|
|||
|
rm bar # donc bar n'existe pas
|
|||
|
|
|||
|
# [ -f foo ] = vrai si le fichier foo existe
|
|||
|
# [ ! -f bar ] = vrai si bar n'existe pas
|
|||
|
|
|||
|
# à n'exécuter que si foo existe ET que bar n'existe pas.
|
|||
|
[ -f foo <strong>-a</strong> ! -f bar ] &&
|
|||
|
mv foo bar
|
|||
|
</pre>
|
|||
|
<p class="continue">Autres formulations possibles :
|
|||
|
</p>
|
|||
|
<pre>
|
|||
|
test -f foo -a ! -f bar
|
|||
|
[ -f foo ] -a [ ! -f bar ]
|
|||
|
[[ -f foo && ! -f bar ]]
|
|||
|
</pre>
|
|||
|
<p><strong>Si vous débutez, vous n'êtes pas tenu de retenir par
|
|||
|
cœur toutes les combinaisons possibles. Sachez simplement les
|
|||
|
reconnaître</strong> si vous les lisez quelque part ; et pour vos
|
|||
|
propres scripts, vous il vous suffit de savoir bien manipuler la syntaxe
|
|||
|
qui vous paraît la plus lisible.</p>
|
|||
|
<h4>Ou : l'opérateur « <code>-o</code> »</h4>
|
|||
|
<p>Pour réaliser la condition de l'opérateur « ou », il suffit
|
|||
|
qu'une seule des conditions qu'il rassemble soit vraie : </p>
|
|||
|
<ul>
|
|||
|
<li> si <em>toutes</em> les conditions sont rassemblées, la condition
|
|||
|
d'ensemble l'est aussi ;</li>
|
|||
|
<li> si <em>une partie seulement</em> de ces conditions est rassemblée,
|
|||
|
la condition d'ensemble l'est aussi ;</li>
|
|||
|
<li> si <em>aucune</em> des conditions incluses n'est remplie, la
|
|||
|
condition d'ensemble ne l'est pas non plus.</li>
|
|||
|
</ul>
|
|||
|
<p>Exemple :</p>
|
|||
|
<pre>
|
|||
|
if [[ "$fichier" == "fichier_interdit" -o ! -f "$fichier" ]]
|
|||
|
then echo "Je ne veux pas lire $fichier ou bien il n'existe pas."
|
|||
|
fi
|
|||
|
</pre>
|
|||
|
<ul>
|
|||
|
<li> si <code>$fichier</code> vaut
|
|||
|
<code>"fichier_interdit"</code>, il n'est pas lu ;</li>
|
|||
|
<li> si <code>$fichier</code> n'existe pas, il n'est pas lu ;</li>
|
|||
|
<li> si <code>$fichier</code> vaut
|
|||
|
<code>"fichier_interdit"</code> et qu'en plus il n'existe pas,
|
|||
|
il n'est pas lu ;</li>
|
|||
|
<li> si <code>$fichier</code> ne vaut pas
|
|||
|
<code>"fichier_interdit"</code> et qu'il existe bien, il est
|
|||
|
lu.</li>
|
|||
|
</ul>
|
|||
|
<h3>
|
|||
|
<a name="s2_2" id="s2_2">Opérateurs arithmétiques</a>
|
|||
|
</h3>
|
|||
|
<p>
|
|||
|
Le shell permet d'opérer des calculs arithmétiques, même s'il est moins
|
|||
|
puissant que d'autres langages (Perl, Scheme, C, etc.) pour cela.
|
|||
|
</p>
|
|||
|
<p>
|
|||
|
Les opérateurs sont les suivants :
|
|||
|
</p>
|
|||
|
<ul>
|
|||
|
<li><code>-eq</code> (<i>equal</i>) : « égal à » (signe
|
|||
|
« = ») ;</li>
|
|||
|
<li><code>-ne</code> (<i>not equal</i>) : « différent
|
|||
|
de » (signe « ≠ ») ;</li>
|
|||
|
<li><code>-gt</code> (<i>greater than</i>) : « strictement
|
|||
|
supérieur à » (signe « > ») ;</li>
|
|||
|
<li><code>-lt</code> (<i>lesser than</i>) : « strictement
|
|||
|
inférieur à » (signe « < ») ;</li>
|
|||
|
<li><code>-ge</code> (<i>greater or equal</i>) : « supérieur
|
|||
|
ou égal à » (signe « ≥ ») ;</li>
|
|||
|
<li><code>-le</code> (<i>lesser or equal</i>) : « inférieur
|
|||
|
ou égal à » (signe « ≤ ») ;</li>
|
|||
|
</ul>
|
|||
|
<p>
|
|||
|
On utilise ces opérateurs entre deux nombres ou variables
|
|||
|
numériques. Par exemple :
|
|||
|
</p>
|
|||
|
<pre>
|
|||
|
#!/bin/sh
|
|||
|
if test 2 -lt 3
|
|||
|
then echo "C'est normal."
|
|||
|
fi
|
|||
|
|
|||
|
if test 2 -gt 3
|
|||
|
then echo "C'est absurde."
|
|||
|
fi
|
|||
|
|
|||
|
petit=2
|
|||
|
grand=3
|
|||
|
|
|||
|
if test $petit -ne 3
|
|||
|
then echo "C'est normal."
|
|||
|
fi
|
|||
|
|
|||
|
if test 2 -eq $grand
|
|||
|
then echo "C'est absurde."
|
|||
|
fi
|
|||
|
</pre>
|
|||
|
<p class="continue">
|
|||
|
Si vous exécutez ce programme, vous obtenez :
|
|||
|
</p>
|
|||
|
<pre>
|
|||
|
C'est normal.
|
|||
|
C'est normal.
|
|||
|
</pre>
|
|||
|
<h3>
|
|||
|
<a name="s2_3" id="s2_3">Opérateurs sur les fichiers</a>
|
|||
|
</h3>
|
|||
|
<p>
|
|||
|
Une grande partie de la puissance du shell se déploie dans sa faculté de
|
|||
|
manipuler des fichiers.
|
|||
|
</p>
|
|||
|
<p>
|
|||
|
Les principaux opérateurs disponibles sont :
|
|||
|
</p>
|
|||
|
<ul>
|
|||
|
<li> nature du fichier :
|
|||
|
<ul><li><code>-e</code> (<i>exists</i>) : vérifie l'existence d'un
|
|||
|
fichier ;</li><li><code>-f</code> (<i>file</i>) : vérifie l'existence d'un
|
|||
|
fichier, et le fait qu'il s'agisse bien d'un fichier au sens
|
|||
|
strict ;</li><li><code>-d</code> (<i>directory</i>) : vérifie l'existence d'un
|
|||
|
répertoire ;</li><li><code>-L</code> (<i>link</i>) : vérifie si le fichier est un
|
|||
|
lien symbolique ;</li></ul></li>
|
|||
|
<li>attributs du fichier :
|
|||
|
<ul><li><code>-s</code> (<i>size</i>) : vérifie qu'un fichier n'est
|
|||
|
pas vide ;</li></ul></li>
|
|||
|
<li>droits sur le fichier :
|
|||
|
<ul><li><code>-r</code> (<i>readable</i>) : vérifie si un fichier peut
|
|||
|
être lu ;</li><li><code>-w</code> (<i>writable</i>) : vérifie si un fichier peut
|
|||
|
être écrit ou modifié ;</li><li><code>-x</code> (<i>writable</i>) : vérifie si un fichier peut
|
|||
|
être exécuté ;</li></ul></li>
|
|||
|
<li>comparaison de fichiers :
|
|||
|
<ul><li><code>-nt</code> (<i>newer than</i>) : vérifie si un fichier
|
|||
|
est plus récent qu'un autre ;</li><li><code>-ot</code> (<i>older than</i>) : vérifie si un fichier
|
|||
|
est plus ancien qu'un autre.</li></ul>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
<p>Exemple :</p>
|
|||
|
<pre>
|
|||
|
#!/bin/sh
|
|||
|
|
|||
|
if test -e ~/.emacs
|
|||
|
then echo "~/.emacs existe."
|
|||
|
else echo "~/.emacs n'existe pas."
|
|||
|
fi
|
|||
|
|
|||
|
if test -d ~/.emacs
|
|||
|
then echo "~/.emacs est un répertoire."
|
|||
|
else echo "~/.emacs n'est pas un répertoire."
|
|||
|
fi
|
|||
|
|
|||
|
if test -f ~/.emacs
|
|||
|
then echo "~/.emacs est un fichier."
|
|||
|
else echo "~/.emacs n'est pas un fichier."
|
|||
|
fi
|
|||
|
|
|||
|
if test ~/.vimrc -nt ~/.emacs
|
|||
|
then "~/.vimrc est plus récent que ~/.emacs."
|
|||
|
fi
|
|||
|
</pre>
|
|||
|
<div class="metainformation">
|
|||
|
Auteur : Baptiste Mélès.
|
|||
|
Dernière modification : 2016-04-22 par Louis Jachiet.
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</body>
|
|||
|
</html>
|