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 :

Comprendre if &&


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 142
    Par défaut Comprendre if &&
    Bonjour

    Je me trouve confronter à problème de syntaxe/incompréhension. le code ci-dessous fonctionne mais pas exactement comme je le veux. Dans la déclaration du if, je cherche a faire un &&. Cela marche mais le shell fait comme si "&& $i != $expr" était quelque chose a éxéctuer et me retourne un message du type : valeur de $i : Permission denied ...

    A ce stade, $i est un chemin. Je veux simplement qu'il vérifie si $i est différents de $expr. Mais il m'écoute pas, il fait ce que je lui dit, pas ce que je veux ... ^^

    Quelqu'un pourrait m'aider à comprendre cette $$@#! de syntaxe ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     if ( ! echo ${tab_exeption[*]} | grep -q $i &&  $i != $expr ) ; then
        gpg --verify $i $strmod"Release" &>/dev/null
        if [ $? != 0 ] ; then
          error=1
          tab_error[$vartab]=$i
          ((vartab++))
        fi
      fi

  2. #2
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Il y a plein de façon de faire, en voilà une :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ( ! echo ${tab_exeption[*]} | grep -q $i &&  [ $i != $expr ] )

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 142
    Par défaut
    Citation Envoyé par matafan Voir le message
    Il y a plein de façon de faire, en voilà une :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ( ! echo ${tab_exeption[*]} | grep -q $i &&  [ $i != $expr ] )
    Merci,

    Mais pourrais-tu m'expliquer ce qui colle pas dans mon truc ?

    De plus, maintenant je me rend compte qu'en fait mon code ne fonctionne pas.

    En toute logique, je voudrais m'assurer que $i ne commence pas par /home. De fait, j'ai initialisé la variable expr à : ^/home/ . Et bien évidemment, ca ne fonctionne pas !

    Bon en tout cas, la modif proposé fonctionne, c'est déjà une erreur de moins !

    Merci

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 142
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ( ! echo ${tab_exeption[*]} | grep -q $i && [[ $i =~ $expr ]] )
    A réglé mon problème de regex.

  5. #5
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 103
    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 103
    Par défaut
    Citation Envoyé par Nelmo Voir le message
    Merci,
    Mais pourrais-tu m'expliquer ce qui colle pas dans mon truc ?
    Bonjour,
    dans la ligne que tu as indiquée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if ( ! echo ${tab_exeption[*]} | grep -q $i &&  $i != $expr ) ; then
      blabla
    fi
    Les parenthèses ne servent à rien: elles ne font que générer un sous-shell inutile. Ce code est donc équivalent à quelque chose comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if cmd1 &&  $i != $expr ; then
      blabla
    fi
    Le shell, lisant de gauche à droite, exécute cmd1 puis, si le résultat est vrai (ou $? == 0), il exécute la suite qui est $i != $expr. Il expanse $i puis considère son résultat comme le nom d'une commande à exécuter, ce qui n'est évidemment pas ce que tu souhaites, et va te sortir un joli message d'erreur, par exemple, si le contenu de $i est "coucou":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ksh: coucou:  not found.
    Manifestement, tu voudrais tester si $i est différent de $expr. Pour cela, il faut exécuter un programme de test, par exemple la commande interne du shell test, soit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if cmd1 &&  test $i != $expr ; then
      blabla
    fi
    qui va faire ce que tu voulais.

    Il existe une autre commande de test. C'est la commande interne du shell [:

    et qui, à ma connaissance, ne fait guère plus que d'appeler test, soit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if cmd1 &&  [ $i != $expr ]; then
      blabla
    fi
    Du coup, on comprend aussi pour quoi il faut absolument une espace avant et après [. Sinon il cherche la commande [$i.

    Ces 2 commandes ont leur équivalent en programme externe ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ ls -l '/usr/bin/[' /usr/bin/test
    -rwxr-xr-x 1 root root 30064 Oct 30  2008 /usr/bin/test*
    -rwxr-xr-x 1 root root 32296 Oct 30  2008 /usr/bin/[*
    Une autre possibilité est d'utiliser une autre fonction de comparaison interne au shell:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if cmd1 &&  [[ $i != $expr ]]; then
      blabla
    fi
    Voilà.
    HTH
    )jack(

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 664
    Par défaut
    Bonjour,

    Citation Envoyé par jack-ft
    Une autre possibilité est d'utiliser la fonction de comparaison interne au shell:
    test et [ sont aussi des commandes internes du shell !
    Il y a de nombreuses commandes internes du shell qui ont leur homonyme sous /bin/.
    Si on n'utilise pas les propriétés avancées de [[, autant utiliser test, ou [.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  7. #7
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 103
    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 103
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    Bonjour,

    test et [ sont aussi des commandes internes du shell !
    Il y a de nombreuses commandes internes du shell qui ont leur homonyme sous /bin/.
    Si on n'utilise pas les propriétés avancées de [[, autant utiliser test, ou [.
    Bonjour,
    je viens de vérifier et j'apprends(!) je confirme que test et [ sont aussi des commandes internes du shell !

    Pour tester "test", il suffit par exemple de faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ echo "echo coucou" > ./test
    $ chmod +x ./test
    $ PATH=.:$PATH
    $ test 3 = 4
    $ echo $?
    1
    Du coup, je vais corriger mon précédent post pour éviter de laisser des informations erronées qui pourraient enduire d'erreur les lecteurs potentiels!

    Par ailleurs, le livre "Le KornShell" de Bolsky et Korn (de 1989-1990), à la page 352, au paragraphe "Caractéristiques obsolètes", indique:
    Attention: les caractéristiques suivantes sont actuellement supportées par ksh uniquement dans un but de compatibilité. Leur utilisation est fortement déconseillée. Ces caractéristiques pourront être supprimées dans le futur:
    - Les options -k et -t de set.
    - echo comme commande intégrée. (utilisez plutôt print).
    - test et [ comme commandes intégrées. (utilisez plutôt [[...]]).
    - La substitution de commande `...`. (utilisez plutôt $(...)).
    - La syntaxe de définition de fonction identificateur(). (utilisez plutôt function identificateur).

    Qu'en pensent nos spécialistes?

    )jack(

+ Répondre à la discussion
Cette discussion est résolue.

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