[EXPECT]inscrire dans fichier+conditions

Résolu
Bonjour,

J'aimerai pouvoir effectuer des commandes sur des équipements Cisco à la chaine (~150 équipements). Pour cela j'ai eu une super idée, qui est d'utiliser la commande expect. J'ai donc suivi un tuto dessus et je maîtrise plus ou moins les bases.

J'ai cependant 2 contraintes auxquelles je suis exposé et où j'ai surtout du mal à me dépatouiller, je suis pas une lumière en Linux, mais plutôt tenace :P

1° La première est que je peux me connecter selon les équipement QUE en telnet où en ssh. J'aimerai dans mon script pouvoir utiliser une condition, le problème est que je ne sais pas quel argument utiliser pour que le script prenne cette condition. Est-il possible de faire quelque chose du style :
if expect "refused" = false then
send "blablabla\r"
else
spawn telnet $argv
...


2° J'aimerai pouvoir récupérer un message généré à partir d'une commande toute bête en cisco "show clock" (qui donne la date et l'heure). J'aimerai récupérer le nom de l'équipement (en paramètre $argv) + cette date et heure, et la mettre séparé par un espace dans un fichier texte. Le problème c'est que j'ai beau essayer de placer mon "> log.txt", il ne le prends pas en compte...L'affichage de cette date et heure est affiché a la ligne, seul, non accompagné quoi :P (pas besoin de grep ou de cut, ou de sed...)

Je vous donne ma config Telnet et SSH (attention, j'ai fais un expect dans un expect :))

#liste des equipements "liste.exp"
#les noms de routeur n'ont rien à voir, donc pas de boucle "for" possible :)"

#!/usr/bin/expect -f
expect "home@local"
send "script.exp routeur1"
expect "home@local"
send "script.exp routeur2"
...

#script telnet contenu dans "script.exp"

#!/usr/bin/expect -f
spawn telnet $argv
expect "Username:"
send "admin\r"
expect "Password:"
send "*******\r"
expect "#"
send "show clock\r"
expect "#"
send "exit\r"
expect "closed"

#script SSH contenu dans "script.exp"

#!/usr/bin/expect -f
spawn ssh $argv
expect "Password:"
send "*******\r"
expect "#"
send "show clock\r"
expect "#"
send "exit\r"
expect "closed"


Merci infiniment pour votre aide !

4 réponses

  1. Modérateur
    Salut,

    Pour le 1 j'ai pas tout pigé ;-\
    Dans le script expect ou dans un script shell (bash ou autre) ?

    Pour le 2, regarde ces 2 discussions sur le forum :
    expect recuperer la date
    passer argument a un script a partir d un fichier

    ;-))
    0
    1. Contributeur
      bonjour, tout d'abord merci pour ton aide =)

      Je vais tout d'abord te détailler un peu ce que je veux faire.

      J'ai des equipements cisco. Tout plein ^^ J'aimerai envoyer des commandes sur ces équipements, comme des commandes qu'on tappe dans le dos, sauf qu'ici ca s'appelle en mode console (enfin pas vraiment, mais admettons :P).
      Je me connecte à cette console à distance de deux façons, selon comment le routeur est configuré :

      - soit en SSH (si le routeur le permet)
      - soit en telnet (par défaut, pour des équipements "bas de gamme" ne supportant pas le SSH)

      Mon but, donc, est de fait un script expect pour automatiser la saisie des commandes sur ces routeurs (qui sont pour tous la même). Le problème, c'est qu'il faut que le script puisse executer une suite de commande particulière si c'est en telnet, et une autre si c'est en SSH (eh vi, la procédure d'authentification est différente...). Sachant qu'en essayant une connexion en SSH il me retourne une erreur "connection refused", j'aurai voulu faire un "if" pour renvoyer vers la suite de commande adaptée pour telnet.

      Mais c'est pas fini ! Je vais créer un deuxième expect, dans lequel je vais mettre la liste de tous les noms de ces routeurs, pour que le script initial se connecte à tout les equipements à la chaine...En gros, je lance le premier script qui fait appel a chaque fois au deuxieme, je pars boire un café tranquillement, je reviens, et il s'est connecté a 200 équipements et rentré 10 lignes de commande pour chaque, tout seul, comme un grand xP

      Et enfin le plus drôle (le clou du spectacle, comme on dit), c'est que de ce script, j'aimerai récupérer 1 ligne généré par l'équipement, qui apparait quand je tappe : "show clock", dans un fichier texte, pour chaque équipement...Le must, c'est que je puisse avoir dans ce fichier le nom du routeur, et à côté le clock, pour comparer les différences d'heure entre les équipements...

      Voilà pour l'histoire, passionnant hein ? :P

      J'espère qu'avec ça tu vas pouvoir un peu mieux comprendre mes codes dans mon premier post.

      Pour tes références, je les avait déjà vu. En ce qui concerne les arguments, j'en ai besoin de qu'un seul, qui est le nom du routeur, donc de ce coté pas de soucis...

      Je pourrais passer le fait que le routeur soit en telnet ou en SSH en argument, mais ça m'embêterai, sachant que j'ai un message d'erreur que je peux "detecter" avec un expect, et que j'aimerai que dans ma liste de mes routeurs je n'ai QUE le nom des routeurs (pour que le script soit réutilisable pour d'autres entrées dans la console).

      Pour la date, je n'en ai pas besoin, mais merci d'avoir cherché la référence pour moi :$

      Merci beaucoup ^_^
      0
  2. Modérateur
    Re-

    Pour ton histoire de "telnet" ou "ssh", regarde cet exemple en cas de mauvaise saisie d'un mot de passe :
    http://www.cotse.com/dlf/man/expect/exp_continue.htm
    peut être qu'en adaptant la commande "exp_continue" à ton cas, ça pourrait le faire...

    Pour ton autre demande, je suis sûr que tu devrais trouver ton bonheur parmi ces commandes ;-))
    0
    1. Contributeur
      Salut !

      Désolé de mettre aussi longtemps pour répondre, j'ai récupéré de la doc sur le script shell, j'ai fais une batterie de tests non stop, corrigé énormément d'erreurs de syntaxe...et trouvé une méthode parfaite pour faire ce que je veux faire :)

      # script_heure_routeur
      
      echo "veuillez donner le mot de passe"
      read password                    # fais un prompt pour le password
      
      rm -f rapport_erreurs.log                         # reinitialise le rapport d'erreurs après chaque migration
      rm -f heure_routeurs.txt                         # reinitialise le fichier d'heures des routeurs après la migration
      rm -f ./routeurs/*                     # reinitialise le dossier où sont contenues tout les logs des équipements foireux
      cat liste.txt | while read routeur;        #liste.txt présente l'ensemble des adresses IP des équipements
      do
      
      expect > tmp_routeur.log 2>/dev/null << EOF                #intégration d'un script expect dans un script shell, suppression de l'affichage des erreurs
      spawn ssh admin@$routeur
      expect "Password:"
      send "$password\r"
      expect "#"
      send "show clock\r"
      expect "#"
      send "exit\r"
      expect "closed"
      exit
      
      EOF
      
           COD_RET=$?                                # contrôle d'erreur sur la bonne execution de la connexion SSH
      
           if [ "$COD_RET" != "0" ]
           then
                echo "Erreur de connexion au routeur $routeur en SSH"
      
      expect > tmp_routeur.log 2>/dev/null << EOF
      spawn telnet $routeur
      send "admin\r"
      expect "Password:"
      send "$password\r"
      expect "#"
      send "show clock\r"
      expect "#"
      send "exit\r"
      expect "closed"
      exit
      EOF
      
                COD_RET=$?              # contrôle d'erreur sur la bonne connexion Telnet
      
                if [ "$COD_RET" != "0" ]
                then
                    echo "erreur de connexion au routeur $routeur en Telnet"
                    rapport=`grep -A2 "spawn" tmp_routeur.log | grep -v "spawn" | grep -v "admin$"`   # récupération du message d'erreur généré après la tentative de connexion
                    echo "$routeur :" $rapport >> rapport_erreurs.log
                    echo "$routeur est Injoignable" >> heure_routeurs.txt
                    cat tmp_routeur.log > ./routeurs/$routeur.log    # récupération du log du routeur déféctueux dans un fichier .log
                    continue
                fi
           fi
            DATE_ROUTEUR_TMP=`grep -A1 "show clock" tmp_routeur.log | grep -v "show clock" | sed 's/^\.//' | sed 's/^\*//' | tr "." " " | cut -d ' ' -f1,3-`                       #récupération, et normalisation de l'heure du routeur (il y a des . et des * des fois devant)
            DATE_ROUTEUR=`date -d "$DATE_ROUTEUR_TMP" '+%d/%m/%y %H:%M:%S'` #Mises aux normes de la date du routeur
            DATE_NTP=`date '+%d/%m/%y %H:%M:%S'`                #Mises aux normes de la date système
            echo -e "$routeur;$DATE_ROUTEUR;$DATE_NTP" >> heure_routeurs.txt          # inscription de  tout ça dans le fichier final
      
            rm -f tmp_routeur.log  #suppression du fichier temporaire
      done
      


      Avec ça, j'execute le script par la commande ./script_heure_routeur j'exporte le fichier texte final en CSV et je l'incorpore dans Excel, ensuite je fais une diff. des deux dates et heures, et je regarde le décalage entre les deux...Si il est de 0, ça va, sinon je me pose des questions...

      J'ai remarqué que tu as tendance à beaucoup renvoyer vers des liens utiles, donc en plus de te copier le script que j'ai écris, je te marquerai sur un post un script pour automatiser la saisie de commandes, adaptables sur des équipements distants, où par le biais de toutes les connexions disponibles par le script EXPECT.

      Bonne journée, problème résolu ;)
      0
      1. Modérateur
        Merci à toi ;-))
        0