100 votes

Que font les options -n et -a dans une déclaration de condition bash?

Quelle fonction exécutent les options -a et -n dans l'instruction bash if suivante ?

if [ -n "$1" -a -n "$2" -a -n "$3" ]; then
    REFNAME=$(basename $3)
else

Les options -a et -n sont-elles appelées les _primitifs_ ?

Signifie -a fichier "Vrai si le fichier existe." ?

222voto

Cory Klein Points 5117

-a Lie deux expressions dans une expression "et" ou "&&". Cette option est obsolète.

-n Vérifie si la longueur d'une chaîne n'est pas nulle.

Vous pouvez traduire l'expression de test en pseudocode comme suit :

if ( ($1 a une longueur non nulle) et
     ($2 a une longueur non nulle) et
     ($3 a une longueur non nulle) )

Cette expression ne vérifie pas si le fichier existe ou n'existe pas, mais seulement si les arguments ont été fournis au script.

Les arguments -a et -n se trouvent dans la page de manuel de test

man test

L'opérateur [ ... ] est souvent utilisé comme raccourci pour test ... et a probablement une fonctionnalité identique sur votre système.

50voto

Sorpigal Points 10412

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X