shell unix: test IF avec plusieurs conditions

shell unix: test IF avec plusieurs conditions - Shell/Batch - Programmation

Marsh Posté le 16-01-2006 à 17:11:03    

bonjour j'ai un petit soucis, je n'arrive pas a faire fonctionner un simple if en 'sh' et non pas en bash.
 
Le premier programme ci-dessous focntionne très bien. Mais le second ne focntionne pas. Si quelqu'un sait comment faire un test avec de multiple test merci d'eclairer ma lanterne   :hello:  
 
PS: j'ai essayer de remplacer les [] par () sans succes.
 
----------PROGRAMME FONCTIONNE------------
 
 
#!/usr/bin/sh
 
echo "START: $0"
 
if [ $# -gt 4 ]
then
   echo " plus de 4 arguments"
   exit 1
fi
 
exit 0
 
----------PROGRAMME FONCTIONNE PAS------------
 
#!/usr/bin/sh
 
echo "START: $0"
 
if [ [ $# -gt 4 ] || [ $# -lt 2 ] ]
then
   echo " plus de 4 arguments ou moins de 2 arguments"
   exit 1
fi
 
exit 0
 
-------------  
 
MERCI D'AVANCE. :jap:


Message édité par mandracke76 le 16-01-2006 à 17:11:32
Reply

Marsh Posté le 16-01-2006 à 17:11:03   

Reply

Marsh Posté le 16-01-2006 à 20:36:00    

Enleve le premier [ et le dernier ] : if [ $# -gt 4 ] || [ $# -lt 2 ]

Reply

Marsh Posté le 17-01-2006 à 14:40:22    

matafan a écrit :

Enleve le premier [ et le dernier ] : if [ $# -gt 4 ] || [ $# -lt 2 ]


 
Merci cela fonctionne.
 
Question subsidiaire:
 
Comment peut on faire  
 
if [ a ] && [ [ B ] || [ C ] ]
then  
...
fi
 
 sans faire:
 
if [ A ]  
then
    if [ B ] || [ C ]
    then
    ...
    fi
fi

Reply

Marsh Posté le 17-01-2006 à 14:51:55    

if [ a ] && [ B ] || [ a ] && [ C ]   :o

Reply

Marsh Posté le 17-01-2006 à 14:55:43    

ritzle a écrit :

if [ a ] && [ B ] || [ a ] && [ C ]   :o


 
tu veux dire qu'il n'y a pas la possibilite du double paranthesage en sh pure  :??:  :??:  :??:

Reply

Marsh Posté le 17-01-2006 à 15:08:12    

mandracke76 a écrit :

tu veux dire qu'il n'y a pas la possibilite du double paranthesage en sh pure  :??:  :??:  :??:


j'en ai aucune idée :D

Reply

Marsh Posté le 17-01-2006 à 15:16:06    

Merci quand même...  :heink:


Message édité par mandracke76 le 17-01-2006 à 15:16:35
Reply

Marsh Posté le 21-01-2006 à 10:33:06    

ritzle a écrit :

if [ a ] && [ B ] || [ a ] && [ C ]   :o


NON !
Déjà, il faut savoir que les crochets en shell sont un raccourci syntaxique sur la commande "test".
Donc l'écriture "[ a ]" s'écrit aussi "test a"
 
De plus, la commande "test" contient déjà ses propres connecteurs "et" et "ou" qui sont "-a" et "-o". D'un point de vue processeur, il vaut mieux lancer une seule fois la commande "test" en y incluant toute son expression logique plutôt que de l'appeler 4 fois (dont une fois de trop)
Enfin les parenthèses sont autorisées... mais comme il s'agit d'un métacaractère shell, il faut les protéger par des backslashes.
 
Donc l'instruction ci-dessus peut avantageusement être remplacée par
"if test a -a \( B -o C \)" ou bien "if [ a -a \( B -o C \) ]"
 
Attention, comme la commande "test" a besoin de bien distinguer quoi va être comparé avec quoi, il faut séparer les éléments les un des autres par un espace => "if.[.a.-a.\(.B.-o.C.\).]" (le "." montrant qu'on doit mettre un espace impérativement)
 
Cours complet de shell ici http://fr.lang.free.fr/cours/Shell_v1.4.pdf
 


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 22-01-2006 à 00:12:52    

/home/nicolas $ type test
test is a shell builtin

Reply

Marsh Posté le 24-01-2006 à 22:40:39    

matafan a écrit :

/home/nicolas $ type test
test is a shell builtin



Ben oui, la commande "test" est interne au shell. Mais tu as aussi un exécutable "/bin/test" ou "/usr/bin/test" qui est accessible. J'ai trouvé il y a longtemps une différence minime entre les deux mais je me souviens plus quoi.
 
Tu as aussi la même chose au sujet de la commande "pwd" et "/bin/pwd". La première te montre le chemin que tu as tapé, même si t'es dans un lien symbolique, l'autre te donne ton emplacement exact.


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 24-01-2006 à 22:40:39   

Reply

Marsh Posté le 25-01-2006 à 04:02:54    

Ce que je voulais dire c'est que la remarque

Sve@r a écrit :

D'un point de vue processeur, il vaut mieux lancer une seule fois la commande "test" en y incluant toute son expression logique plutôt que de l'appeler 4 fois (dont une fois de trop)http://fr.lang.free.fr/cours/Shell_v1.4.pdf


n'a pas lieu d'être, puisqu'il n'y a pas de fork/exec.

Reply

Marsh Posté le 25-01-2006 à 22:54:32    

matafan a écrit :

Ce que je voulais dire c'est que la remarque
 
n'a pas lieu d'être, puisqu'il n'y a pas de fork/exec.


Non mais il y a probablement un déroutement quelconque et appel d'une sous routine (je fais un parallèle avec le peu d'assembleur que je connais). Mieux vaut un seul déroutement que 4
 
De plus, tu sais pas ce que fait l'instruction "a" dans "if [ a ] && [ B ] || [ a ] && [ C ]" mais il n'empêche qu'elle est appelée 2 fois et rien que ça c'est déjà dommage.
 
Maintenant imagine le test suivant (syntaxiquement tout à fait correct)

if [ -z `grep bidule machin |awk '{gros script}'` ] && [ -n "$var1" ] || [ -z `grep bidule machin |awk '{gros script}'` ] && [ -n "$var2" ]


 
Si le fichier "machin" est énorme et que le "gros script" est lui-aussi très long, tu imagines les processus inutiles et le temps bouffé pour rien (sans compter le temps pour simplement taper cet immondice 2 fois) ???
 

if [ -z `grep bidule machin |awk '{gros script}'` -a \( -n "$var1" -o -n "$var2" \) ]


C'est quand-même plus fin comme test (même s'il y a mieux encore).
 
Maintenant, entre

if [ $# -gt 4 ] || [ $# -lt 2 ]


et

if [ $# -gt 4 -o  $# -lt 2 ]


C'est vrai que ça doit pas changer grand chose... mais enseigner la première méthode à qqun qui ne connait pas le shell risque de lui donner de mauvaises habitudes et le mener vers une voie où il ne saura pas écrire autrement un test complexe qu'en répétant les instructions.
 
Au pire on peut écrire "if [ a ] && \( [ B ] || [ C ] \)" mais puisque les connecteurs "and" et "or" sont déjà inclus dans le test, pourquoi s'en priver ? Laissons le "&&" et "||" aux programmes qui n'ont que ça...


Message édité par Sve@r le 25-01-2006 à 23:13:29

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 20-03-2006 à 15:38:18    

Merci beaucoup et désolé pour le retard de reponse finale.
Mais dans mon cas cela n'etait que de simple comparaisons numériques banales donc cela n'a pas trop d'impacte au niveau execution. Mais je note quand même l'information syntaxique concernant la commande "TEST".

Reply

Marsh Posté le 24-03-2006 à 18:56:25    

mandracke76 a écrit :

Merci beaucoup et désolé pour le retard de reponse finale.
Mais dans mon cas cela n'etait que de simple comparaisons numériques banales donc cela n'a pas trop d'impacte au niveau execution. Mais je note quand même l'information syntaxique concernant la commande "TEST".


 
En fait, il peut y avoir quand-même avantage à écrire

if test A || test B


 
par rapport à

if test A -o B


 
(A et B étant des tests divers et variés)
 
Dans la première écriture, si "A" renvoie "vrai", "B" ne sera pas évalué... alors qu'il le sera dans la seconde écriture. Cela peut être utile dans des cas spéciaux d'optimisation de rapidité...


Message édité par Sve@r le 24-03-2006 à 18:56:57

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed