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 :

Problème boucle for


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Janvier 2011
    Messages
    179
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 179
    Par défaut Problème boucle for
    Bonjour,

    je suis sur un script afin de détecter sur des ports sur des équipements CISCO le spanning tree et leurs coûts.

    Mon script fonctionne bien pour un seul host. Quand j’intègre à mon script une boucle afin de lire ligne par ligne un fichier d'hôtes, mon script ne lit que la 1ere ligne et s'arrête sans que je sache pourquoi

    si quelqu'un pouvait m'expliquer le pourquoi du comment et me débuguer ! merci à vous par avance !

    (inutile de vous dire que j'ai vérifié mon fichier texte, il est sous un bon format et j'ai bien une entrée par lignes )


    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    #!/bin/bash
     
    #########################################################################################
    #                                                                                       #
    #                                                                                       #
    #   Requirements:               snmpwalk, snmpget (available in NetSNMP package)        #
    #   Last modification:          03/06/2014                                              #
    #   Purpose of this plugin:     detection de cout STP sur les ports			    		#
    #                                                                                       #
    #   Arguments:                                                                          #
    #                ./check-multi-stp-cisco.sh community snmp_version 	    				#
    #                                            $1          $2                         	#
    #########################################################################################
     
    # fichier de correspondance
     
    file_stp='/usr/local/nagios/type_stp.txt'
     
    # fichier cisco
     
    list_cisco=`cat /usr/local/nagios/cisco.txt `
     
    # OID STP cisco
     
    OID_STP_COST='1.3.6.1.2.1.17.2.15.1.5'
    OID_PORT_STP='1.3.6.1.2.1.17.2.15.1.3'
    OID_DESC_PORT='1.3.6.1.2.1.17.1.4.1.2'
    OID_STP_TYPE='1.3.6.1.4.1.9.9.82.1.6.1'
     
    for a in $list_cisco
     
    do
     
    # on vérifie l'état du STP sur le switch
    type_stp=$(snmpwalk -c $1 -v$2 $a $OID_STP_TYPE | awk {'print $4'})
    type_stp_label=$(cat $file_stp | grep -w $type_stp | cut -d ":" -f2)
     
     
    # on regarde le nombre de ports qu'il y a de configuré en STP
    ports_stp=$(snmpwalk -c $1 -v$2 $a $OID_PORT_STP | cut -d"." -f12 | cut -d'=' -f1 | wc -l)
     
    	if [ $ports_stp = 0 ]
    		then 
    		echo "pas de ports en STP"
    		exit 0
     
    	elif test $(snmpwalk -c $1 -v$2 $a $OID_PORT_STP | cut -d"." -f12 | cut -d'=' -f1 | wc -l ) -gt 1
    		then
    			for (( i=$( snmpwalk -c $1 -v$2 $a $OID_PORT_STP | cut -d"." -f12 | cut -d'=' -f1 | wc -l) ; i>0 ; i-=1 ))
    				do		
    					ports_stp_isole=$(snmpwalk -c $1 -v$2 $a $OID_PORT_STP | cut -d"." -f12 | cut -d'=' -f1 | tail -n $i | head -n 1)
    					cout_ports_stp_isole=$(snmpwalk -c $1 -v$2 $a $OID_STP_COST.$ports_stp_isole | awk {'print $4'} | tail -n $i | head -n 1)
    					PORTS_isole=$(snmpwalk -c $1 -v$2 $a $OID_DESC_PORT.$ports_stp_isole | awk {'print $4'} | tail -n $i | head -n 1)
    					ports_desc_stp_isole=$(snmpwalk -c $1 -v$2 $a IF-MIB::ifDescr.$PORTS_isole | awk {'print $4'} | tail -n $i | head -n 1)
    					stp=$"[le cout de $ports_desc_stp_isole est de $cout_ports_stp_isole]"
    					total_stp="$total_stp $stp"
    				done
     
    					echo $a est en $type_stp_label
    					echo $total_stp
    					exit 1
     
    			echo erreur de script
    			exit 2
    	fi 
     
    done

  2. #2
    Membre confirmé
    Inscrit en
    Janvier 2011
    Messages
    179
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 179
    Par défaut
    ah j'ai trouvé mon erreur, problème avec mes exit 0/1/2 :p

    je les ai retiré, ça fonctionne maintenant

  3. #3
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : IS Consultant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Par défaut
    Bonjour.

    Bon ton problème est passé en résolu, mais je vais quand même me permettre quelque remarque sur ton script

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    list_cisco=`cat /usr/local/nagios/cisco.txt `
    ###
    for a in $list_cisco
    do
    done
    Cette façon de lire un fichier est totalement à proscrire ! Je te recommande de lire ces quelques liens :

    Quelques bonnes pratiques dans l'écriture de scripts en Bash
    [FAQ] Pourquoi faut-il éviter d'utiliser la boucle for sur une sortie de commande ?
    [FAQ] Comment lire/parcourir un fichier ?

    En gros ça traite de comment lire un fichier correctement en Bash (ne jamais utiliser cat pour lire un fichier car c'est totalement inutile et pas prévu pour ça et de manière générale éviter le for pour lire une sortie de commande).

    ---------------------------------

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    # on vérifie l'état du STP sur le switch
    type_stp=$(snmpwalk -c $1 -v$2 $a $OID_STP_TYPE | awk {'print $4'})
    awk ici c'est un peu comme sortir l'artillerie lourde pour pas grand chose, surtout que Bash sait très bien gérer ce genre de cas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    # on vérifie l'état du STP sur le switch
    read -ra outSnmpwalk < <(snmpwalk -c $1 -v$2 $a $OID_STP_TYPE)
    type_stp="${outSnmpwalk[3]}"
    ---------------------------------

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    type_stp_label=$(cat $file_stp | grep -w $type_stp | cut -d ":" -f2)
    Le cat est à nouveau totalement superflus ! grep sait très bien lire un fichier en entrée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    type_stp_label=$(grep -w "$type_stp" "$file_stp" | cut -d ":" -f2)
    Bon là il faut savoir que Bash aurrait pu savoir remplacer le cut à l'aide d'un changement d'IFS, mais bon cut est très bien adapté pour les petits découpages de ce type.
    Si on voulais éviter la multiplication de processus, un awk aurait pu convenir également :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    type_stp_label=$(awk -F ":" -vword="$type_stp" '($0 ~ word){print $2}' "$file_stp")
    Si l'option "-w" de grep était indispensable, on peux compenser par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    type_stp_label=$(awk -F ":" -vword="$type_stp" '($0 ~ "^(.* )?"word"( .*)?$"){print $2}' "$file_stp")
    Bien sûr ici je chipote un peu, le grep + cut c'est ce que j'aurais probablement utilisé, mais c'est pour sensibiliser au fait qu'il faille toujours réfléchir à éviter la multiplication des processus inutilement (cat|grep|cut par exemple).

    ---------------------------------

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    # on regarde le nombre de ports qu'il y a de configuré en STP
    ports_stp=$(snmpwalk -c $1 -v$2 $a $OID_PORT_STP | cut -d"." -f12 | cut -d'=' -f1 | wc -l)
    Dès lors qu'il y a plusieurs délimiteurs, awk devient plus adapté que cut :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -F "[.=]" '{print $1}'
    ---------------------------------

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if [ $ports_stp = 0 ]
    		then 
    		#...
     
    	elif test $(snmpwalk -c $1 -v$2 $a $OID_PORT_STP | cut -d"." -f12 | cut -d'=' -f1 | wc -l ) -gt 1
    Bon ici, je m'abstiendrais de commentaire sur l'identation (bien que ce soit quand même quelque chose de très important y compris dans l'écriture de script shell)

    Quelques remarques toutefois sur cet extrait :

    1) Il faut choisir les bons opérateurs dans son test ;
    2) Il faut protéger ses opérandes.
    3) Je trouve curieux le mélange de syntaxe (test et [) et d'opérateurs

    ---------------------------------

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    elif test $(snmpwalk -c $1 -v$2 $a $OID_PORT_STP | cut -d"." -f12 | cut -d'=' -f1 | wc -l ) -gt 1
    #...
    for (( i=$( snmpwalk -c $1 -v$2 $a $OID_PORT_STP | cut -d"." -f12 | cut -d'=' -f1 | wc -l) ; i>0 ; i-=1 ))
    do	
         ports_stp_isole=$(snmpwalk -c $1 -v$2 $a $OID_PORT_STP | cut -d"." -f12 | cut -d'=' -f1 | tail -n $i | head -n 1)
         cout_ports_stp_isole=$(snmpwalk -c $1 -v$2 $a $OID_STP_COST.$ports_stp_isole | awk {'print $4'} | tail -n $i | head -n 1)
         PORTS_isole=$(snmpwalk -c $1 -v$2 $a $OID_DESC_PORT.$ports_stp_isole | awk {'print $4'} | tail -n $i | head -n 1)
         ports_desc_stp_isole=$(snmpwalk -c $1 -v$2 $a IF-MIB::ifDescr.$PORTS_isole | awk {'print $4'} | tail -n $i | head -n 1)
    # ...
    Il semble qu'il y ai beaucoup de redondance sur les appels et le découpage des retour de snmpwalk, malheureusement je connais pas cette commande.
    Peut être qu'en nous fournissant un flux entrant et ce que tu souhaites en retirer, nous pourrions t'indiquer des solutions davantage optimales...

    Cordialement,
    Idriss

  4. #4
    Rédacteur/Modérateur
    Avatar de Winnt
    Homme Profil pro
    budget et contrôle de gestion
    Inscrit en
    Décembre 2006
    Messages
    1 978
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France

    Informations professionnelles :
    Activité : budget et contrôle de gestion
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 978
    Par défaut
    Chipoteur
    Mais toujours intéressantes comme remarques.
    Je tâcherai de les avoir à l'esprit lorsque je ferai un script.
    Winnt
    Merci de lire les règles du forum LaTeX et Qu'est ce qu'un ECM ?.
    N'hésitez pas à parcourir la FAQ la réponse y est peut-être déjà.
    Pensez au bouton si votre problème est résolu.


    C'est en Linuxant qu'on devient .... geek
    Et c'est en LateXant qu'on devient flemmard
    Mon blog tout neuf.
    Articles : présentation de la distribution Gentoo, Les index sous LaTeX et leur personnalisation.

  5. #5
    Membre confirmé
    Inscrit en
    Janvier 2011
    Messages
    179
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 179
    Par défaut
    hello !

    merci pour ta réponse

    bon apparemment, c'est pas aussi bien et optimisé que ça :p mais ça à le mérite de fonctionner ^^

    en gros, c'est un script pour nagios pour faire de la supervision.

    le SNMP sert à ça, le fait d'installer net-snmp sur un linux te permet de passer des commandes et d'avoir des retours sur des équipements, car chaque équipement à une MIB qui sommeille en lui et donc le fait d'interroger en Read Only (RO) une certain OID te renverra une information que tu pourras traiter, ce qui va donc plus vite que de te connecter en ssh, de passer une commande et de récupérer le retour de ta commande sur l'équipement

    pour te montrer un exemple, voilà ce que fait du SNMPWALK sur un équipement cisco (c'est lié par rapport à mon script) :
    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
    38
    39
     
    file='/usr/local/nagios/stp.txt'
    #1:disabled
    #2:blocking
    #3:listening
    #4:learning
    #5:forwarding
    #6:broken
     
    # OID PORT : 1.3.6.1.2.1.17.1.4.1.2
    # on récupère donc le 52 et 108 avec un : cut -d"." -f12 | cut -d'=' -f1
     
    root [/usr/local/nagios/libexec] > snmpwalk -c adelweb94public -v1 occis4 1.3.6.1.2.1.17.1.4.1.2
    iso.3.6.1.2.1.17.1.4.1.2.52 = INTEGER: 10152
    iso.3.6.1.2.1.17.1.4.1.2.108 = INTEGER: 10652
     
     
     
    # OID STATUS : 1.3.6.1.2.1.17.2.15.1.3
    # le 52 et 108 qu'on a recup avant on le met à la fin de l'OID et on a l'état et on le compare avec le fichier d'état 
     
    root [/usr/local/nagios/libexec] > snmpwalk -c adelweb94public -v1 occis4 1.3.6.1.2.1.17.2.15.1.3.52
    iso.3.6.1.2.1.17.2.15.1.3.52 = INTEGER: 2
    ¨
     
    # OID Description port : 1.3.6.1.2.1.2.2.1.2
    # on trouve la description du port avec l'OID du port (avant) sauf que là on recupère la valeur après l'INTEGER 
    # cad : 10152 et 10652
     
    root [/usr/local/nagios/libexec] > snmpwalk -c adelweb94public -v1 occis4 1.3.6.1.2.1.2.2.1.2.10152
    iso.3.6.1.2.1.2.2.1.2.10152 = STRING: "GigabitEthernet1/0/52"
     
    # l'affichage voulu sera du genre :
     
    GigabitEthernet1/0/52 - blocking
    GigabitEthernet2/0/52 - forwarding
     
    # donc pour les états 2 et 5 = OK
    # et le truc infâme : si un port est en 2 ou 5, si son état change = afficher un CRITQUE avec la cause
    si avec tout ce que tu m'as dis, tu me trouves un moyen d'optimiser, de fluidifier et de sécuriser tout mon code, je suis preneur !

    merci encore à toi pour ton retour et tes conseils forts utiles

  6. #6
    Membre confirmé
    Inscrit en
    Janvier 2011
    Messages
    179
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 179
    Par défaut
    je pense qu'avec des "case" par exemple ça serait mieux que de lire un fichier qui comporte mes erreurs etc. (tu me diras si je me trompe )

    mais je sais pas faire :p

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

Discussions similaires

  1. Problème boucle for
    Par revsys dans le forum Delphi
    Réponses: 20
    Dernier message: 24/05/2007, 15h50
  2. Problème boucle for
    Par rouliane dans le forum C++
    Réponses: 2
    Dernier message: 14/12/2006, 14h37
  3. [VBA-E, Débutant] Problème Boucle for
    Par strifer dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 24/08/2006, 12h30
  4. [Débutant] Problème boucle for
    Par toniooooo dans le forum Langage
    Réponses: 10
    Dernier message: 18/04/2006, 14h42
  5. [FLASH 8] Problème Boucle For
    Par Begood dans le forum Flash
    Réponses: 6
    Dernier message: 21/03/2006, 11h36

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