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 :

[BASH] Problème choix 'case'


Sujet :

Shell et commandes GNU

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Technicien réseau
    Inscrit en
    Décembre 2017
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Technicien réseau
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2017
    Messages : 53
    Points : 32
    Points
    32
    Par défaut [BASH] Problème choix 'case'
    Bonjour,

    J'ai un petit problème avec mon script bash. Pour expliquer l'idée de ce bash, je souhaiterais récupéré l'ip d'une machine en fonction de son interface (eth0 ou bond0). Donc j'ai mis mes commandes (qui fonctionne) dans des variables et je les ai testé avec un eval, cela fonctionne. Puis j'ai essayé de mettre en place un case en fonction de ma commande d'obtention de l'interface et là, rien ne s'affiche.

    Voici le code bash :

    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
     
    #!/bin/bash
     
    OBTENTION_INTERFACE="ifconfig | awk '{print "'$1'","'$2'"}' |  grep -v '127.0.*' | awk '{print "'$1'"}' | grep -v 'inet6' | grep -B 1 'inet' | sed '1!d' | sed 's/://g'"
     
    IP_BOND0="ifconfig bond0 | grep 'inet\|inet addr:' | awk '{print "'$2'"}' | cut -d ":" -f 2"
    IP_ETH0="ifconfig eth0 | grep 'inet\|inet addr:' | awk '{ print "'$2'"}' | cut -d ":" -f 2"
     
    case $OBTENTION_INTERFACE in
      'eth0')
        eval $IP_ETH0
      ;;
     
      'bond0')
        eval $IP_BOND0
      ;;
     
    esac
    donc quand j'essaie de faire un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     eval $OBTENTION_INTERFACE
    en dehors du case, j'obtiens : Puis je fais un et j'obtiens bien mon Donc je me posais la question, pourquoi en dehors du 'case' ça marche et quand j'assemble le tout, je n'obtiens rien.

    Merci d'avance pour vos réponses et bonne journée.

    Max

  2. #2
    Nouveau membre du Club
    Homme Profil pro
    Technicien réseau
    Inscrit en
    Décembre 2017
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Technicien réseau
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2017
    Messages : 53
    Points : 32
    Points
    32
    Par défaut
    J'ai une question qui pourrait m'aider à régler le soucis, est-ce que lorsque qu'on met : case $OBTENTION_INTERFACE in, ça exécute le contenu de la variable OBTENTION_INTERFACE et en fonction du résultat, ça te fait soit ce qui est contenu dans l'option eth0 ou l'option bond0 ?

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Technicien réseau
    Inscrit en
    Décembre 2017
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Technicien réseau
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2017
    Messages : 53
    Points : 32
    Points
    32
    Par défaut
    Problème résolu.

    Voici le changement à faire :

    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
     
    #!/bin/bash
    OBTENTION_INTERFACE=$(ifconfig  | awk '{print $1,$2}' | grep -v '127.0.*' | awk '{print $1}' | grep -v 'inet6' | grep -B 1 'inet' | sed '1!d' | sed 's/://g')
     
    IP_BOND0="ifconfig bond0 | grep 'inet\|inet addr:' | awk '{print "'$2'"}' | cut -d ":" -f 2"
    IP_ETH0="ifconfig eth0 | grep 'inet\|inet addr:' | awk '{ print "'$2'"}' | cut -d ":" -f 2"
     
    case "$OBTENTION_INTERFACE" in
      "eth0")
        eval $IP_ETH0
      ;;
     
      "bond0")
        eval $IP_BOND0
      ;;
    esac

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2010
    Messages
    345
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 345
    Points : 539
    Points
    539
    Par défaut
    Salut,
    Pour eviter l'empilement de grep, cut, awk ...
    awk peut le faire seul :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ifconfig|awk '/^eth0/||/^bond0/{f=$1}f&&/inet/{print f FS $2;exit}'
    Cordialement.

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Technicien réseau
    Inscrit en
    Décembre 2017
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Technicien réseau
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2017
    Messages : 53
    Points : 32
    Points
    32
    Par défaut
    Merci beaucoup pour cette amélioration.

    J'aime bien regardé pas à pas ce que j'obtiens au niveau de mes commandes shell, c'est pour ça que je cumule les grep/sed/awk/cut :p

    J'aurais une dernière question, j'ai certaines machines qui sont sous la forme "inet addr:<ip>" dans le ifconfig, comment tu rajoutes cette option sur ta commande ? J'ai essayé de |/ ou encore des || mais j'ai un peu de mal avec les expressions awk :p

    Si tu as le temps de me répondre, je t'en remercie par avance ! Bonne journée

  6. #6
    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 Xam29870 Voir le message
    Problème résolu.

    Voici le changement à faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #!/bin/bash
    OBTENTION_INTERFACE=$(ifconfig  | awk '{print $1,$2}' | grep -v '127.0.*' | awk '{print $1}' | grep -v 'inet6' | grep -B 1 'inet' | sed '1!d' | sed 's/://g')
    
        eval $IP_ETH0
    Attention! "eval" is evil...

    Et la gestion des guillemets ne marche pas comme tu sembles l'écrire.

    De plus, l'écriture de variables shell en majuscules est traditionnellement réservée pour les variables système.

    Pour revenir à "eval", j'ai l'impression que tes variables contiennent juste du code.
    Or, il existe, dans le langage shell, une entité spécifiquement dédiée à cette fonction: la fonction!

    Voici une proposition (non testée):

    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
    #!/bin/bash
    obtention_interface=$(ifconfig|awk '/^eth0/||/^bond0/{f=$1}f&&/inet/{print f FS $2;exit}')
     
    ip_bond0() {
        ifconfig bond0 | grep 'inet\|inet addr:' | awk '{print "'$2'"}' | cut -d ":" -f 2
    }
     
    ip_eth0() {
        ifconfig eth0 | grep 'inet\|inet addr:' | awk '{ print "'$2'"}' | cut -d ":" -f 2
    }
     
    case "$obtention_interface" in
      "eth0")
        ip_eth0
      ;;
     
      "bond0")
        ip_bond0
      ;;
    esac
    Mais, on peut aussi faire plus simple:

    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
    #!/bin/bash
    obtention_interface=$(ifconfig|awk '/^eth0/||/^bond0/{f=$1}f&&/inet/{print f FS $2;exit}')
     
    ip_1() {
        ifconfig "$1" | grep 'inet\|inet addr:' | awk '{print "'$2'"}' | cut -d ":" -f 2
    }
     
    case "$obtention_interface" in
      "eth0")
        ip_1 "eth0"
      ;;
     
      "bond0")
        ip_1 "bond0"
      ;;
    esac
    que l'on peut également simplifier en:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/bin/bash
    obtention_interface=$(ifconfig|awk '/^eth0/||/^bond0/{f=$1}f&&/inet/{print f FS $2;exit}')
     
    ip_1() {
        ifconfig "$1" | grep 'inet\|inet addr:' | awk '{print "'$2'"}' | cut -d ":" -f 2
    }
     
    case "$obtention_interface" in
      eth0|bond0)
        ip_1 "$obtention_interface"
      ;;
    esac
    Voire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #!/bin/bash
    obtention_interface=$(ifconfig|awk '/^eth0/||/^bond0/{f=$1}f&&/inet/{print f FS $2;exit}')
     
    ifconfig "$obtention_interface" | grep 'inet\|inet addr:' | awk '{print "'$2'"}' | cut -d ":" -f 2
    Ou même:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #!/bin/bash
     
    ifconfig $(ifconfig|awk '/^eth0/||/^bond0/{f=$1}f&&/inet/{print f FS $2;exit}') | grep 'inet\|inet addr:' | awk '{print "'$2'"}' | cut -d ":" -f 2
    Après, je ne sais pas comment continuer à simplifier...

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2010
    Messages
    345
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 345
    Points : 539
    Points
    539
    Par défaut
    Bonjour,
    J'aurais une dernière question, j'ai certaines machines qui sont sous la forme "inet addr:<ip>" dans le ifconfig, comment tu rajoutes cette option sur ta commande ? J'ai essayé de |/ ou encore des || mais j'ai un peu de mal avec les expressions awk :p
    Comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ifconfig | awk '/^eth0/||/^bond0/{f=$1}f&&/inet/{sub(/[^0-9]*/,"",$2);print f FS $2;exit}'
    Uniquement l'adresse ip comme dans ton script :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ifconfig | awk '/^eth0/||/^bond0/{f=$1}f&&/inet/{sub(/[^0-9]*/,"",$2);print $2;exit}'
    Cordialement.

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Technicien réseau
    Inscrit en
    Décembre 2017
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Technicien réseau
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2017
    Messages : 53
    Points : 32
    Points
    32
    Par défaut
    Merci grandement à vous deux !

    Bonne journée

  9. #9
    Nouveau membre du Club
    Homme Profil pro
    Technicien réseau
    Inscrit en
    Décembre 2017
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Technicien réseau
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2017
    Messages : 53
    Points : 32
    Points
    32
    Par défaut
    Désolé pour toute ses questions, mais j'aimerais vraiment m'améliorer en bash et je suis débutant !

    Une dernière petite question après j'arrête promis

    Si je veux savoir si mon ip récupérait à partir de mon interface équivaut à une plage d'adresse IP (10.0.*) ou au contraire, n'est pas dans cette plage, je dois faire un truc comme ça ? :

    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
     
    #!/bin/bash
     
    obtention_interface=$(ifconfig  | awk '{print $1,$2}' | grep -v '127.0.*' | awk '{print $1}' | grep -v 'inet6' | grep -B 1 'inet' | sed '1!d' | sed 's/://g')
     
    ip_interface() {
      ifconfig "$1" | grep 'inet\|inet addr:' | awk '{print $2}' | cut -d ":" -f 2 | head -1
    }
     
    valeur="10.0.*"
     
    case "$obtention_interface" in
      eth0|bond0)
         ip_interface $obtention_interface
         if [ $? -eq $valeur ] ; then
             echo "L'ip trouve est contenu dans la plage "10.0.*" "
         elif [ $? -ne $valeur ] ; then
             echo "L'ip trouve n'est pas contenu dans la plage "10.0.*""
         else
             echo "erreur"
         fi
      ;;
    esac
    Merci d'avance et à bientôt !

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2010
    Messages
    345
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 345
    Points : 539
    Points
    539
    Par défaut
    Re
    Un petit tour vers man bash peut être !
    Pas besoin d'utiliser 'case' ici :
    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
    val_IP=$(/sbin/ifconfig | awk '
      /^eth0/||/^bond0/ {
        f=1
      }
      f && /inet/ {
        sub(/[^0-9]*/,"",$2)
        print $2
        exit
      }
    ')
    # val_IP contient la valeur de l'ip récupéré avec awk
    valeur="10.0.*"
    # valeur va être traité comme un regex grace aux [[
    if [[ "$val_IP" =~ $valeur ]] ; then
      echo "L'ip trouvé $val_IP est contenu dans la plage $valeur"
    else
      echo "L'ip trouvé $val_IP n'est pas contenu dans la plage $valeur"
    fi
    Pour le fun, tout dans awk !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    /sbin/ifconfig | awk -v 'a=10.0.*' '
      /^eth0/ || /^bond0/ {
        f=1
      }
      f && /inet/ {
        sub( /[^0-9]*/ , "" , $2 )
        if ( $2 ~ a )
          g = "est"
        else
          g = "n\047est pas"
        print "L\047ip trouvé " $2 " " g " contenu dans la plage " a
        exit
      }'
    Cordialement.

  11. #11
    Membre habitué
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Décembre 2013
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Décembre 2013
    Messages : 70
    Points : 159
    Points
    159
    Par défaut
    Bonsoir !
    Citation Envoyé par ctac_ Voir le message
    Pour le fun, tout dans awk !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /sbin/ifconfig | awk -v 'a=10.0.*'
    Cordialement.
    Pour le chipotage :p :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /sbin/ifconfig | awk -v 'a=10\.0\.\*'...
    Rajout :
    en fait, je chipote mal !! Faut initialiser la variable "a" comme ça, du moins avec gawk :

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2010
    Messages
    345
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 345
    Points : 539
    Points
    539
    Par défaut
    Bonjour,
    Postmortem a raison.
    a=10.0.* est un masque pas un regex.
    Je propose de créer le regex directement dans le code.
    De cette façon, Xam29870 n'auras pas à chercher le regex qui va bien
    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
    /sbin/ifconfig | awk -v 'a=10.0.*' '
      /^eth0/ || /^bond0/ {
        f=1
      }
      f && /inet/ {
        sub( /[^0-9]*/ , "" , $2 )
        r=a
        gsub( /[.][*]/ , " " , r )
        gsub( /[.]/ , "\\." , r )
        gsub( " " , ".*" , r )
        if ( $2 ~ r )
          g = "est"
        else
          g = "n\047est pas"
        print "L\047ip trouvé " $2 " " g " contenu dans la plage " a
        exit
      }'
    Le problème est le même avec bash :
    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
    val_IP=$(/sbin/ifconfig | awk '
      /^eth0/||/^bond0/ {
        f=1
      }
      f && /inet/ {
        sub(/[^0-9]*/,"",$2)
        print $2
        exit
      }
    ' )
    # val_IP contient la valeur de l'ip récupéré avec awk
    valeur="10.0..*"
    # création du regex qui va être traité grace aux [[
     
    regex="${valeur//.\*/ }"
    regex="${regex//./\\.}"
    regex="${regex// /.*}"
     
    if [[ "$val_IP" =~ $regex ]] ; then
      echo "L'ip trouvé $val_IP est contenu dans la plage $valeur"
    else
      echo "L'ip trouvé $val_IP n'est pas contenu dans la plage $valeur"
    fi
    Citation Envoyé par Postmortem Voir le message
    en fait, je chipote mal !! Faut initialiser la variable "a" comme ça, du moins avec gawk :
    ça fonctionne aussi avec mawk.
    Cordialement.

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

Discussions similaires

  1. [bash] Problème avec case .. in
    Par fabweso_71 dans le forum Shell et commandes GNU
    Réponses: 2
    Dernier message: 01/12/2015, 17h05
  2. Problème SELECT, CASE et Group by
    Par Royd938 dans le forum MS SQL Server
    Réponses: 9
    Dernier message: 03/10/2014, 07h41
  3. Problème switch case
    Par Nelmo dans le forum MFC
    Réponses: 8
    Dernier message: 04/05/2006, 15h17
  4. [PL SQL] Problème avec 'case' dans une fonction
    Par divail dans le forum Oracle
    Réponses: 14
    Dernier message: 13/03/2006, 15h50
  5. [VBA] problème choix de cellule dans feuille excel
    Par beegees dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 01/02/2006, 10h48

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