Pinaillage
Les commutateurs -a
et -n
ne font pas strictement partie d'une déclaration bash
if
dans la mesure où la commande if
ne traite pas ces commutateurs.
Qu'est-ce que les primaires?
Je les appelle "commutateurs", mais la documentation bash
que vous avez liée se réfère à la même chose en tant que "primaires" (probablement parce que c'est un terme commun utilisé lorsqu'on discute des parties d'une expression booléenne).
Contexte et docs
Dans les scripts sh
, if
est une commande qui prend une commande en argument, l'exécute et teste son code de retour. Si le code de retour est 0
, le bloc de code suivant then
est exécuté jusqu'au fi
de fermeture ou (si fourni) le else
suivant. Si le code de retour n'était pas 0
et qu'une déclaration else
a été fournie, alors le bloc de code suivant else
est exécuté jusqu'au fi
de fermeture.
Vous pouvez voir cet effet en passant à if
la commande true
ou la commande false
, qui sont des commandes simples qui ne font rien et renvoient respectivement 0
et non-0
.
if true ; then echo true était vrai ; else echo true était faux ; fi
if false ; then echo false était vrai ; else echo false était faux ; fi
Dans le code d'exemple que vous avez fourni, la commande que vous passez à if
est [
, qui est parfois aussi appelée test
. C'est cette commande qui prend les commutateurs dont vous parlez. Dans bash
, la commande test
sera une commande intégrée ; essayez type [
pour en apprendre le type. Pour les commandes intégrées, help
montrera l'utilisation, alors exécutez aussi help [
pour voir la documentation. Votre système a probablement aussi un /bin/[
et un /bin/test
et si vous man test
, vous pourrez voir les manuels pour ceux-ci. Bien que le comportement de la commande intégrée test
ne soit pas identique au comportement documenté dans les pages de manuel, qui est probablement plus détaillé que la simple description que vous obtiendrez de help [
, il décrira probablement assez précisément le comportement de la commande intégrée [
.
Le comportement de -a et -n
Sachant que la commande que vous exécutez est test
, nous pouvons consulter help test
ou man test
et lire son utilisation. Cela montrera que -n
teste l'argument suivant et évalue à vrai s'il n'est pas une chaîne vide.
Dans la documentation de test
, vous verrez également le commutateur -e
. Ce commutateur teste l'argument suivant et évalue à vrai si cet argument est un fichier ou un répertoire qui existe. Encore plus utile est le commutateur -f
qui évalue à vrai si l'argument suivant existe et est un fichier régulier (par opposition à un répertoire ou un bloc de périphérique, ou autre).
La source de votre confusion est probablement qu'il peut y avoir deux formes de -a
: unaire et binaire. Lorsque -a
est utilisé dans un contexte unaire, c'est-à-dire avec un argument suivant mais pas d'arguments précédents, il traite son argument comme un fichier et teste son existence, tout comme le commutateur -e
. Cependant, lorsque -a
est utilisé dans un contexte binaire, c'est-à-dire avec un argument avant et un argument après, il traite ses arguments comme d'autres conditions et agit comme un opérateur booléen ET.
Dans un souci de portabilité, il est important de noter que l'unaire -a
est une extension non standard qui ne sera pas trouvée dans POSIX. Cependant, elle est disponible dans bash
et ksh
, donc son utilisation est probablement répandue.
Exemple
cd /tmp
if [ -a fichier-test ] ; then
echo 1: fichier-test existe
else
echo 1: fichier-test manquant
fi
touch fichier-test
if [ -a fichier-test ] ; then
echo 2: fichier-test existe
else
echo 2: fichier-test manquant
fi
var=quelquechose
if [ -n "$var" -a -a fichier-test ] ; then
echo la variable var n'est pas vide et le fichier-test existe
fi
rm -f fichier-test