Test

De wiki.nexiat.fr
Aller à la navigation Aller à la recherche
Fiche express
Domaine Test conditionnel shell
Commande test, [ ], [[ ]]
Contexte Scripts shell (POSIX sh/bash)
Voir aussi Bash (extensions), Grep

test (et son alias historique [ ]) évalue une expression et retourne un code de sortie : 0 si vraie, 1 si fausse — récupérable via $?. C'est la brique de base des conditions if/while en shell. Bash ajoute en plus [[ ]], une commande composée plus permissive (pas besoin de guillemets autour des variables, comparaisons par motif, opérateur =~ pour les regex).

Syntaxe de base

test -f /etc/passwd
echo $?              # 0 si le fichier existe

[ -f /etc/passwd ]    # équivalent, syntaxe crochet
echo $?

if [ -f /etc/passwd ]; then
  echo "le fichier existe"
fi

Tests sur les fichiers

[ -e fichier ]     # le fichier existe (quel que soit son type)
[ -f fichier ]     # fichier régulier
[ -d fichier ]     # répertoire
[ -L fichier ]     # lien symbolique
[ -p fichier ]     # tube nommé (FIFO)
[ -S fichier ]     # socket
[ -b fichier ]     # périphérique bloc
[ -c fichier ]     # périphérique caractère

[ -r fichier ]     # droit de lecture
[ -w fichier ]     # droit d'écriture
[ -x fichier ]     # droit d'exécution
[ -s fichier ]     # taille non nulle (fichier non vide)

[ -u fichier ]     # bit setuid positionné
[ -g fichier ]     # bit setgid positionné
[ -k fichier ]     # sticky bit positionné
[ -O fichier ]     # appartient à l'UID effectif courant
[ -G fichier ]     # appartient au GID effectif courant

[ fichier1 -nt fichier2 ]  # fichier1 plus récent que fichier2 (newer than)
[ fichier1 -ot fichier2 ]  # fichier1 plus ancien que fichier2 (older than)
[ fichier1 -ef fichier2 ]  # même fichier (mêmes device+inode, ex. lien physique)

Tests sur les chaînes de caractères

[ -n "$chaine" ]           # vrai si la chaîne n'est pas vide
[ -z "$chaine" ]           # vrai si la chaîne est vide

[ "$a" = "$b" ]            # vrai si les chaînes sont égales
[ "$a" != "$b" ]           # vrai si les chaînes sont différentes
[ "$a" \< "$b" ]           # comparaison lexicographique (échapper < et >)
[ "$a" \> "$b" ]

Avec [[ ]] (bash uniquement), pas besoin de quoter les variables ni d'échapper </>, et == accepte un motif à droite :

[[ $a == $b ]]        # comparaison de motif (glob), pas seulement égalité stricte
[[ $fichier == *.log ]]   # vrai si $fichier se termine par .log
[[ $chaine =~ ^[0-9]+$ ]] # vrai si $chaine est une regex étendue (POSIX ERE)

Tests numériques

[ "$a" -eq "$b" ]   # égal
[ "$a" -ne "$b" ]   # différent
[ "$a" -lt "$b" ]   # inférieur (less than)
[ "$a" -le "$b" ]   # inférieur ou égal
[ "$a" -gt "$b" ]   # supérieur (greater than)
[ "$a" -ge "$b" ]   # supérieur ou égal

# équivalent arithmétique, plus lisible en bash :
(( a < b ))

Combinaisons logiques

[ -f fichier ] && [ -r fichier ]   # ET, recommandé (deux tests séparés)
[ -f fichier ] || echo "absent"    # OU

[[ -f fichier && -r fichier ]]     # ET directement dans [[ ]]
[[ -f fichier || -d fichier ]]     # OU directement dans [[ ]]

[ ! -f fichier ]                   # négation

Les opérateurs historiques -a (ET) et -o (OU) internes à [ ] sont dépréciés (POSIX les marque obsolètes, ambigus dès qu'on combine plusieurs conditions) — préférer &&/|| entre deux [ ] distincts, ou passer à [[ ]] qui les supporte nativement sans ambiguïté.

`[ ]` vs `[[ ]]`

[ ] est un alias de la commande test (POSIX, disponible dans tous les shells sh) : les variables non quotées ou contenant des espaces/caractères spéciaux peuvent casser l'expression, d'où la nécessité de toujours écrire "$var". [[ ]] est une commande composée spécifique à bash (et ksh/zsh) : plus sûre côté quoting, elle ajoute la correspondance de motif et les regex, mais n'est pas portable dans un script #!/bin/sh strict (dash, busybox sh…).

Voir aussi

  • Bash — extensions bash au shell POSIX
  • Grep — tester des motifs sur du texte plutôt que sur des variables