444 lines
15 KiB
HTML
444 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>
|