Vous n'êtes pas identifié(e).
L'icône rouge permet de télécharger chaque page du wiki visitée au format PDF et la grise au format ODT →
Ceci est une ancienne révision du document !
En interne, bash dispose de plusieurs commandes pour réaliser des tests sur des paramètres, des chaînes de caractères, des fichiers ou encore faire des comparaison numériques :
Les commandes [ et test sont disponibles dans leurs versions externe : /usr/bin/[ et /usr/bin/test.
Elles ont toutes les deux la même page de manuel (man [ ou man test).
Les commandes internes disposent des opérateurs que n'ont pas les commandes externes.
Rappels :
Les commandes de test disposent de deux opérateurs unaires pour tester si une chaîne est vide (de longueur nulle) ou pas.
Syntaxe :
test OP chaîne [ OP chaîne ] [[ OP chaîne ]] Chaîne est sujette au développement des paramètres. Avec pour OP, l'un des opérateur du tableau suivant.
Si l'opérande contient des espaces, il doit être protégé.
Opérateurs de test sur chaîne | |
Opérateurs | Retours |
---|---|
-z | Vrai si chaîne de longueur nulle |
-n | Vrai si chaîne de longueur non nulle |
L'opérateur -n peut-être omis.
test -z ; echo $? #Test si vide et affiche le code retour [ -n "" ] ; echo $? #Test si non vide et affiche le code retour [[ "" ]] ; echo $? #Test si non vide et affiche le code retour
0 1 1
test -z "mot" ; echo $? [[ -n "Linux" ]] ; echo $? [[ "GNU Linux" ]] ; echo $?
1 0 0
v="Debian GNU Linux" test -z "$v" ; echo $? v="" [ -n "$v" ] ; echo $? unset v # Supprime le paramètre v [[ -z "$v" ]] ; echo $? [ "$v" ] ; echo $?
1 0 0 1
Les opérateurs -z et -n sont des opérateurs unaires, il n'accepte qu'un seul opérande (argument).
Si sa valeur contient des espaces, il doit être protégé par des guillemets doubles.
p="Debian Facile" test -z $p ; echo $? unset p
bash: test: Debian : opérateur binaire attendu 2
Rappel : Lorsqu'une commande interne renvoie un code de retour 2, cela signifie un mauvais usage de cette commande.
L'opérateur -n revoie un code de retour inattendu, quand un paramètre vide est testé sans protection.
Sauf avec la commande [[.
test -n $p ; echo $? [ -n $p ] ; echo $? p="" [[ -n $p ]] ; echo $? unset p
0 0 1
Avec l'opérateur -z, nous pouvons nous affranchir de la protection des guillemets en utilisant le remplacement des paramètre et l'opérateur +.
(Voir Substitution de la valeur d'un paramètre)
p="Debian GNU Linux" test -z ${p+x} ; echo $? unset p [[ -z ${p+x} ]] ; echo $?
Lors du développement (remplacement) d'un paramètre, l’opérateur + permet, si la valeur du paramètre est non nulle, de la substituée par une autre valeur (ici x).
Avec l'opérateur -n les guillemets restent nécessaires au cas ou le paramètre mémorise une chaîne vide, sauf avec la commande [[.
p="Debian Facile" [[ -n ${p+x} ]] ; echo $? [[ -${p+x} ]] ; echo $? unset p [[ -n ${p+x} ]] ; echo $? [[ -${p+x} ]] ; echo $?
0 0 1 1
Les commandes de test disposent d'opérateurs binaires pour comparer deux chaînes entre elles.
Syntaxe :
test chaîne1 OP chaîne2 [ chaîne1 OP chaîne2 ] [[ chaîne1 OP chaîne2 ]] Chaîne1 et chaîne2 sont sujettes au développement des paramètres. Avec pour OP, l'un des opérateur du tableau suivant.
Si un opérande (chaîne1 ou chaîne2) est une chaîne vide, ou contient des espaces, il doit être protégé, placé entre guillemets simples ou doubles.
Opérateurs de comparaison sur les chaînes | |
Opérateurs | Significations |
---|---|
= | Correspond à |
== | Synonyme de = |
!= | Ne correspond pas |
< | Vrai si chaine1 est placée lexicographiquement avant chaine2 |
> | Vrai si chaine2 est placée lexicographiquement après chaine2 |
[[ $a == "z*" ]] # vrai si $a est égal à z* [[ $a == z* ]] # vrai si $a commence avec un "z" (reconnaissance de modèles) [[ "$a" < "$b" ]] # vrai si $a se trouve avant $b dans le dictionnaire
-posix :
[ "$a" = "z*" ] # vrai si $a est égal à z* [ "$a" \< "$b" ] # vrai si $a se trouve avant $b dans le dictionnaire
test "GNU" == "GNU" ] ; echo $? [[ "GNU" != "GNU Linux" ]] ; echo $?
Donc la chaîne “GNU” est identique à elle-même ;), mais pas à “GNU Linux”.
v1="Debian GNU Linux" v2="Debian Facile" if [ "$v1" = "$v2" ] then echo 'vrai' else echo 'faux' fi unset v1 v2
Donc les deux chaînes contenues dans les variables v1 et v2 ne sont pas égales.
Les deux opérandes sont obligatoires.
test GNU == ; echo $? [[ != LINUX ]] echo $?
echo $? bash: test: GNU : opérateur unaire attendu 2 bash: opérateur binaire conditionnel attendu bash: erreur de syntaxe près de « LINUX » 2
Les espaces entre les opérandes et l'opérateur sont obligatoires.
[ "GNU Linux"=="LINUX" ] ; echo $?
Sans espace entre les opérande et l'opérateur “GNU Linux”==“LINUX” est compris comme une chaîne de caractère.
N'étant pas nulle, le test n'échoue pas.
Copions le code suivant dans le fichier mon_script.
#!/bin/bash var1="def" var2="def" if [ "$var1" == "$var2" ] ; then echo "1) \$var1 ($var1) correspond(==) à \$var2 ($var2)." fi var3="hip" var4="hip" if test "$var3" = "$var4" ; then echo "2) \$var3 ($var3) correspond(=) à \$var4 ($var4)." fi
bash mon_script rm -v mon_script
1) $var1 (def) correspond(==) à $var2 (def). 2) $var3 (hip) correspond(=) à $var4 (hip). 'mon_script' supprimé
Les commandes de test permettent de réaliser des test de comparaison lexicographique.
(voir https://debian-facile.org/atelier:chantier:bash-comparaison-lexicographique-des-chaines.)
#!/bin/bash a="sloiuy" b="aktgjaùkjayaj" if [[ $a < $b ]] ; then echo "OK l'opérateur < fonctionne avec les chaînes de caractère" fi echo " " if [[ $a > $b ]] ; then echo "Les opérateurs < et > signifient avant et après selon l'ordre alphabétique (doubles crochets) " fi echo " " if [ $a \> $b ] ; then echo "Les opérateurs \< et \> signifient avant et après selon l'ordre alphabétique (simples crochets) " fi
./mon_script
OK L'opérateur < fonctionne avec les chaînes de caractère Les opérateurs < et > signifient avant et après selon l'ordre alphabétique (doubles crochets) Les opérateurs \< et \> signifient avant et après selon l'ordre alphabétique (simples crochets)
Avec les commandes [ ou test, les opérateur < et > doivent être protégés.
(Voir Comparaison lexicographique avec [ ou test.)
Les commandes de tests disposent d'opérateurs permettant de réaliser des comparaison numérique.
Voir Comparaison numérique avec [ (ou test) et [[
Le shell bash permet d'effectuer aussi des tests sur les fichiers avec la commande interne composée [[ ]]
et la commande interne [ ]
(associées à if ou non).).
if [[ option $FICHIER ]]
Extrait de la page du manuel de bash section CONDITIONS | |
Opérateurs | Retours : |
---|---|
-a fichier | Vrai si le fichier existe. |
-b fichier | Vrai si le fichier existe et est un fichier spécial bloc. |
-c fichier | Vrai si le fichier existe et est un fichier spécial caractère. |
-d fichier | Vrai si le fichier existe et est un répertoire. |
-e fichier | Vrai si le fichier existe. |
-f fichier | Vrai si le fichier existe et est un fichier normal. |
-g fichier | Vrai si le fichier existe et a son bit Set-GID positionné. |
-h fichier | Vrai si le fichier existe et est un lien symbolique. |
-k fichier | Vrai si le fichier existe et a son bit « sticky » positionné. |
-p fichier | Vrai si le fichier existe et est un tube nommé (FIFO). |
-r fichier | Vrai si le fichier existe et est accessible en lecture. |
-s fichier | Vrai si le fichier existe et a une taille strictement positive. |
-t df | Vrai si le descripteur de fichier df est ouvert et se rapporte à un terminal. |
-u fichier | Vrai si le fichier existe et a son bit Set-UID positionné. |
-w fichier | Vrai si le fichier existe et est accessible en écriture. |
-x fichier | Vrai si le fichier existe et est exécutable. |
-G fichier | Vrai si le fichier existe et appartient au GID effectif du groupe. |
-L fichier | Vrai si le fichier existe et est un lien symbolique. |
-N fichier | Vrai si le fichier existe et a été modifié depuis sa dernière lecture. |
-O fichier | Vrai si le fichier existe et appartient à l'UID effectif de l'utilisateur. |
-S fichier | Vrai si le fichier existe et est une socket. |
fichier_1 -ef fichier_2 | Vrai si le fichier_1 et le fichier_2 se rapportent au même périphérique et ont les mêmes numéros d'inœuds. |
fichier_1 -nt fichier_2 | Vrai si le fichier_1 est plus récent que le fichier_2 (selon les dates de dernière modification) ou si fichier_1 existe et non fichier_2. |
fichier_1 -ot fichier_2 | Vrai si le fichier_1 est plus ancien que le fichier_2 ou si fichier_2 existe et non fichier_1. |
Remarque : L'opérateur -e teste si le fichier existe quelque soit son statut (fichier, répertoire, lien, etc).
Soit le script mon_script.
#!/bin/bash var1="~/toto" if [ -f "$var1" ] then echo "le fichier existe !" else echo "fichier non trouvé ! Car il n'y a pas de développement du ~ entre guillemets (simples ou doubles)." fi var1=~/toto # Sans guillemets, le ~ est développé. if [ -f "$var1" ] then echo "le fichier existe ! (Sans guillemets, le développement du ~ c'est réalisé)." else echo "fichier inexistant !" fi var1="home/hypathie/toto" if [ -f "$var1" ] then echo "le fichier existe !" else echo "fichier inexistant !" fi if test -f "$var1" then echo "le fichier existe !" else echo "fichier inexistant !" fi
touch ~/toto bash mon_script rm -v ~/toto
fichier non trouvé ! Car il n'y a pas de développement du ~ entre guillemets (simples ou doubles). le fichier existe ! (Sans guillemets, le développement du ~ c'est réalisé). le fichier existe ! le fichier existe ! '/home/hypathie/toto' supprimé
Tests dans un terminal des commande test et [.
touch ~/toto test -f /home/hypathie/toto echo $? [ -f ~/toto ] echo $? rm -v ~/toto
0 0 '/home/hypathie/toto' supprimé
Et voilà !