IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

Test arithmétique dans un script


Sujet :

Shell et commandes GNU

  1. #1
    Membre actif
    Inscrit en
    Octobre 2005
    Messages
    908
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 908
    Points : 271
    Points
    271
    Par défaut Test arithmétique dans un script
    Bonjour,
    J'ai un souci de débutant concernant les tests arithmétiques dans un script shell... j'ai un peu (beaucoup) honte mais après de nombreux test et recherches, je ne comprend rien...
    Voici ma batterie de tests :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    full=false
    if [ ! $full ];then
    echo "test 1"
    else
    echo "test 1 : else !"
    fi
    # exécute le else
     
    full=false
    if [ $full ];then
    echo "test 2 : then !"
    fi
    # exécute le then
     
    full=true
    if [ $full ];then
    echo "test 3"
    fi
    # exécute le then
     
    if [ true ];then
    echo "test 4"
    fi
    # exécute le then
     
    if [ false ];then
    echo "test 5 : then !"
    fi
     
    if [ $full -eq false ];
    # ERREUR: [: true : nombre entier attendu comme expression
     
    if test $full -eq false
    # ERREUR: test: true : nombre entier attendu comme expression
     
    if test $full -eq $false
    # ERREUR: test: true : opérateur unaire attendu
    Quelqu'un pourrait-il m'expliquer (avec un GROS SVP) :
    1/ pourquoi le test 1 passe dans else
    2/ pourquoi le test 2 passe dans then
    3/ pourquoi le test 5 passe dans else
    4/ les 3 dernières erreurs
    5/ comment faire un test sur une variable boolean !

    Merci d'avance !

  2. #2
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 386
    Points
    19 386
    Par défaut
    Bonjour,

    en gros (parce que je ne vais pas faire tes exos), $full contient une chaîne false.

    plus loin, c'est le code de retour des commandes true, puis false qui est testé (c'est un test booléen) : le code de retour d'une commande est zéro (vrai), ou supérieur (faux).

    les chaînes dans les tests devraient toujours être entre guillemets.

    quant à comparer une chaîne avec un nombre : on ne peut comparer des chèvres et des choux !
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 280
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 280
    Points : 12 729
    Points
    12 729
    Par défaut
    Bonjour,

    Je pense que le monsieur voulait mettre dans une variable le retour de la commande true ou false...

    Et la syntaxe, n'est certainement pas var=commande et d'ailleurs ni var=$(commande) ou var=`commande` car ici c'est le retour de la commande qui nous intéresse et non pas sa sortie.
    Cordialement.

  4. #4
    Membre actif
    Inscrit en
    Octobre 2005
    Messages
    908
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 908
    Points : 271
    Points
    271
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    $full contient une chaîne false.!
    Comment déclare-t-on une variable de type booléen alors !??? Je ne trouve rien de concret sur la toile.

    Citation Envoyé par N_BaH Voir le message
    le code de retour d'une commande est zéro (vrai), ou supérieur (faux).
    ah oui quand même... j'ai toujours (dans d'autre langages) vu vrai=1 partant de là c'est sûr je vais avoir des problèmes.

    Citation Envoyé par N_BaH Voir le message
    les chaînes dans les tests devraient toujours être entre guillemets.
    ok je comprends c'est comme pour "protéger" les chemins de fichiers contenant des espaces...

    Citation Envoyé par N_BaH Voir le message
    quant à comparer une chaîne avec un nombre : on ne peut comparer des chèvres et des choux !
    oui d'accord... mais Shell Bourne n'est pas très friendly

    Bon, malgré ces remarques je ne vois pas comment avoir une variable de type boolean, pour ensuite la tester à la manière d'un flag !


  5. #5
    Membre actif
    Inscrit en
    Octobre 2005
    Messages
    908
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 908
    Points : 271
    Points
    271
    Par défaut
    Je suis désolé mais y a beaucoup (trop?) de subtilité...

    Citation Envoyé par disedorgue Voir le message
    Je pense que le monsieur voulait mettre dans une variable le retour de la commande true ou false...
    true et false sont des commandes ???

    Citation Envoyé par disedorgue Voir le message
    c'est le retour de la commande qui nous intéresse et non pas sa sortie.
    le retour et la sortie n'est pas la même chose ?

  6. #6
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 280
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 280
    Points : 12 729
    Points
    12 729
    Par défaut
    Il n'y a pas de variable de type booléen en shell, une fonction ou une commande peut te faire un retour booléen mais c'est tout.
    A partir du moment ou tu le vérifie depuis une variable, tu auras une valeur à comparer:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $ true
    $ toto=$?
    $ [ $toto -ne 0 ] && echo ko || echo ok
    ok
    $ false
    $ toto=$?
    $ [ $toto -ne 0 ] && echo ko || echo ok
    ko
    PS: le '$' en début de chaque ligne est mon prompt.
    Cordialement.

  7. #7
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 386
    Points
    19 386
    Par défaut
    Citation Envoyé par disedorgue
    Je pense que le monsieur voulait mettre dans une variable le retour de la commande true ou false...

    Et la syntaxe, n'est certainement pas var=commande et d'ailleurs ni var=$(commande) ou var=`commande` car ici c'est le retour de la commande qui nous intéresse et non pas sa sortie.
    je suis d'un doute concernant ce que j'ai dit, car lors du développement d'une variable qui contient une commande, la commande est exécutée.
    c'est une chose que finalement je fais assez rarement.
    le retour et la sortie n'est pas la même chose ?
    non, le retour c'est ce qu'affiche la commande, le code de retour ne s'affiche que sur demande avec la variable $?, parce qu'il n'est pas toujours nécessaire de l'afficher pour l'utiliser..
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  8. #8
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 243
    Points : 13 458
    Points
    13 458
    Par défaut
    Bonjour,

    ah oui quand même... j'ai toujours (dans d'autre langages) vu vrai=1 partant de là c'est sûr je vais avoir des problèmes.
    Certes. Mais lorsqu'un programme marche, il n'y a rien a dire. Alors que quand il ne marche pas, il faut retourner un code erreur pour expliquer le dysfonctionnement. Il est donc beaucoup plus judicieux de prendre pour convention "0"="tout marche" et ">=1"="code erreur" que l'inverse "0"="faux" et "autre nombres"="toujours vrai".

    Surtout pour un langage de script ...

    oui d'accord... mais Shell Bourne n'est pas très friendly
    Si l'informatique était friendly, elle ne s'exprimerait pas en binaire
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  9. #9
    Membre actif
    Inscrit en
    Octobre 2005
    Messages
    908
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 908
    Points : 271
    Points
    271
    Par défaut
    Citation Envoyé par Flodelarab Voir le message
    Certes. Mais lorsqu'un programme marche, il n'y a rien a dire. Alors que quand il ne marche pas, il faut retourner un code erreur pour expliquer le dysfonctionnement. Il est donc beaucoup plus judicieux de prendre pour convention "0"="tout marche" et ">=1"="code erreur" que l'inverse "0"="faux" et "autre nombres"="toujours vrai".
    ça se tiens comme raisonnement...

    Citation Envoyé par Flodelarab Voir le message
    Si l'informatique était friendly, elle ne s'exprimerait pas en binaire

  10. #10
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par Tchupacabra Voir le message
    Je suis désolé mais y a beaucoup (trop?) de subtilité...

    le retour et la sortie n'est pas la même chose ?
    Je définis 2 fonctions:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ foo() { echo 'Foo'; return 0; }
    $ bar() { echo 'Bar'; return 1; }
    Puis, je les appelle:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $ foo
    Foo    # <- ça, c'est la sortie
     
    $ echo $?
    0      # <- et ça, c'est le code retour
     
     
    $ bar
    Bar    # <- ça, c'est la sortie
     
    $ echo $?
    1      # <- et ça, c'est le code retour
    Donc, non, la sortie et le code retour, ce n'est pas la même chose! CQFD

    Citation Envoyé par Tchupacabra Voir le message
    true et false sont des commandes ???
    Farpaitement!
    Disedorgue l'a montré ici

    D'ailleurs, je dirais qu'il vaut mieux définir les fonctions foo et bar de cette manière:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ foo() { echo 'Foo'; true; }
    $ bar() { echo 'Bar'; false; }
    Remarque: il y a 2 manières de tester le code retour:

    1) placer la commande directement dans un "if" (ou dans un enchaînement avec "&&" et "||")
    2) récupérer dans une variable le code retour et tester le contenu de cette variable

    Méthode 1:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ if foo; then echo 'Foo a retourné TRUE'; else echo 'Foo a retourné FALSE'; fi
    Foo
    Foo a retourné TRUE
     
    $ if bar; then echo 'Bar a retourné TRUE'; else echo 'Bar a retourné FALSE'; fi
    Bar
    Bar a retourné FALSE
    Méthode 2:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    f$ foo
    Foo
     
    $ status=$?
     
    $ if test $status -eq 0; then echo 'Foo a retourné TRUE'; else echo 'Foo a retourné FALSE'; fi
    Foo a retourné TRUE
     
    idem pour bar
    Je trouve la méthode 1) meilleure quoique moins habituelle:
    - elle est plus fonctionnelle
    - elle marche même si on ne sait pas qu'une fonction a un code retour
    - elle marche même si on ne connaît pas l'existence de $?
    - elle marche même si on ne sait pas que 0=true
    - elle facilite grandement l'utilisation de l'option "set -e"
    - elle permet de ne pas se prendre la tête avec les crochets (simples, doubles, parenthèses, accolades?) qui sont souvent le cauchemar des débutants!
    - elle permet d'inverser facilement le test avec if ! foo; then etc.Inconvénient: dans un shell sans la commande "!" (ça existe!), le test inverse avec "if" est lourd!


    Je trouve que la méthode 2) est source de confusion:
    - elle casse la logique de la valeur retournée qui passe de la pile (j'imagine) vers une variable, puis qui passe de variable à argument d'une fonction "test" qui retransforme cet argument en valeur de retour (mise sur la pile, j'imagine) et enfin testée par la fonction "if".

    - elle nécessite de connaître la valeur 0=true

    - elle est source de bugs classiques:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ bar
    Bar
    echo "status: $?"
    status: 1
    if [ $? -eq 0 ]; then echo ok; fi
    ok
    Bon, après, ce n'est que ma modeste opinion!
    Peut-être les spécialistes ont une vision différente!
    Mais les coups et les douleurs... même en informatique...

Discussions similaires

  1. Réponses: 3
    Dernier message: 09/06/2012, 21h40
  2. Deux tests dans un script
    Par malik0 dans le forum Shell et commandes GNU
    Réponses: 4
    Dernier message: 28/03/2012, 11h46
  3. Comment empécher les @ dans mon script de test d'eMail actuel ?
    Par Jean-Seba dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 24/07/2011, 17h57
  4. Script shell 2 test grep dans un if
    Par hoaivong dans le forum Linux
    Réponses: 4
    Dernier message: 13/11/2008, 20h46
  5. test de connexion dans un script batch
    Par pasfute dans le forum Connexions aux bases de données
    Réponses: 1
    Dernier message: 03/07/2007, 16h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo