shell unix: test IF avec plusieurs conditions - Shell/Batch - Programmation
Marsh Posté le 16-01-2006 à 20:36:00
ReplyMarsh 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
Marsh Posté le 17-01-2006 à 14:55:43
ritzle a écrit : if [ a ] && [ B ] || [ a ] && [ C ] |
tu veux dire qu'il n'y a pas la possibilite du double paranthesage en sh pure
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
Marsh Posté le 17-01-2006 à 15:16:06
Merci quand même...
Marsh Posté le 21-01-2006 à 10:33:06
ritzle a écrit : if [ a ] && [ B ] || [ a ] && [ C ] |
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
Marsh Posté le 22-01-2006 à 00:12:52
ReplyMarsh Posté le 24-01-2006 à 22:40:39
matafan a écrit :
|
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.
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.
Marsh Posté le 25-01-2006 à 22:54:32
matafan a écrit : Ce que je voulais dire c'est que la remarque |
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...
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".
Marsh Posté le 24-03-2006 à 18:56:25
mandracke76 a écrit : Merci beaucoup et désolé pour le retard de reponse finale. |
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é...
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
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.
Message édité par mandracke76 le 16-01-2006 à 17:11:32