2016-02-24 3 views
-1

J'ai écrit un script pour vous connecter via ssh et exécuter des commandes. La moitié des appareils sur la liste de ma liste d'appareils ont une combinaison de nom d'utilisateur et de mot de passe acceptable différente.Parcourez plusieurs identifiants possibles TCL Expect

Je veux attendre à pouvoir interpréter l'échec de connexion, lancez une nouvelle tentative de connexion avec le même appareil, mais utilisent des identifiants de connexion à la deuxième tentative (il y a deux combinaisons nom d'utilisateur et mot de passe possibles)

Si n'importe qui peut me diriger dans la bonne direction, je l'apprécierais vraiment. C'est ma première fois en utilisant TCL ou attendre.

Une version condensée de ce que j'ai jusqu'ici est ci-dessous.

set username "someusername" 
set password "somepassword" 

set devices "X.X.X.X" 

foreach device $devices { 
    puts "Processing device: $device"; 
    spawn plink -ssh $devices 

    expect "Store key in cache" 
    send "y\r" 

    expect "login as:" 
    send "$username\r" 

    expect "password:" 
    send "$password\r" 
    expect "#" 

send "conf t\r" 
expect "(config)#" 

send "some commands\r" 
expect "(config)#" 

send "end\r" 
expect "#" 

send "copy run startup-config\r" 
expect "#" 
+0

Saviez-vous que 'foreach' peut itérer sur deux ou plusieurs listes à la fois? 'foreach device $ devices nom d'utilisateur $ noms d'utilisateur mot de passe $ mots de passe {...}'. Cela peut rendre ce genre de chose plus facile ... –

+0

Je ne savais pas que Donal. Merci! Je pense que même si le foreach avait plus d'une liste, TCL quitterait après la première tentative ratée. De plus, les appareils Cisco auxquels je suis connecté ne ré-invitent pas le nom d'utilisateur après la saisie du mauvais mot de passe, donc je pense qu'en plus de pouvoir passer plus d'un ensemble de variables d'authentification, le script devrait pouvoir démarrer une nouvelle session utilisant le même $ device à partir de $ devices. Je ne suis pas sûr que ce soit le cas, à mon avis. Si non, je suis content d'être réglé. – helloworldhello

Répondre

1

Vous devez probablement quelque chose comme

set usernames [list name1 name2] 
set passwords [list pw1 pw2 ] 

set devices [list X.X.X.X ...] 

foreach device $devices { 
    puts "Processing device: $device"; 
    spawn plink -ssh $devices 

    set auth_idx -1 

    expect { 
     "Store key in cache" {send "y\r"; exp_continue} 

     "login as:" { 
      incr auth_idx 
      if {$auth_idx == [llength $usernames]} { 
       puts "login failed for $device" 

       # close the plink connection. I'm guessing here 
       send \003  ;# Ctrl-C 
       expect eof 

       # and on to the next device 
       continue 
      } 

      send "[lindex $usernames $auth_idx]\r" 
      expect "password:" 
      send "[lindex $passwords $auth_idx]\r" 

      # and wait for either the command prompt or another login prompt 
      exp_continue 
     } 

     "#" 
    } 

    # ... whatever you do when you're logged in 

    # and logout. something like 
    send "quit\r" 
    expect eof 
} 

Il utilise exp_continue à "boucle" dans le même s'attendre à déclaration. Je suppose que vous ne devez pas toujours stocker la clé dans le cache. Je suppose que vous voyez « se connecter comme » si la première tentative de connexion échoue


MISE À JOUR

set usernames [list name1 name2] 
set passwords [list pw1 pw2 ] 

set devices [list X.X.X.X ...] 

set device_idx 0 
set auth_idx 0 

while {$device_idx < [llength $devices]} { 
    set device [lindex $devices $device_idx] 

    puts "Processing device: $device"; 
    spawn plink -ssh $devices 

    expect { 
     "Store key in cache" {send "y\r"; exp_continue} 

     "login as:" { 
      send "[lindex $usernames $auth_idx]\r" 
      expect "password:" 
      send "[lindex $passwords $auth_idx]\r" 
      exp_continue 
     } 

     "Access denied" { 
      incr auth_idx 
      if {$auth_idx == [llength $usernames]} { 
       puts "login failed for $device" 
       # next device 
       set auth_idx 0 
       incr device_idx 
      } else { 
       # close the plink connection. I'm guessing here 
       send \003  ;# Ctrl-C 
       expect eof 
       # re-do with current device 
      } 
      continue 
     } 

     "#" 
    } 

    # ... whatever you do when you're logged in 

    # and logout. something like 
    send "quit\r" 
    expect eof 

    # and on to the next device 
    set auth_idx 0 
    incr device_idx 
} 
+0

Merci pour le post Glenn. Super truc! Cette fonctionnalité "incr auth_inx" semble être une grande partie de ce dont j'ai besoin. Si le premier login échoue, est-ce que nous pouvons générer une nouvelle session puis appliquer le second ensemble de creds? Je demande parce que l'appareil cible ne reviendra pas au début des invites de connexion, il continuera à demander le mot de passe pour le nom d'utilisateur qui a été initialement entré et il existe deux noms d'utilisateur différents. i.e. « login comme: somepass someuser @ mot de passe somedevice: Accès refusé someuser @ mot de passe somedevice: Accès refusé le mot de passe someuser @ somedevice: – helloworldhello

+0

@glenjackman Votre solution fonctionne très bien! Cependant, maintenant il y a une autre variable surgissant et c'est la réponse de "Connection expiré" (quand l'hôte cible n'est pas joignable) Puis-je ajouter un "else if" ou quelque chose pour rendre compte de cela? – helloworldhello

+0

Voyez comment je vérifie "clé de magasin"? Ajouter une autre paire 'pattern {condition}' dans la commande expect –