web-dev-qa-db-fra.com

Utilisation d'instructions conditionnelles dans 'expect'

J'ai besoin d'automatiser la connexion à une session TELNET en utilisant attendre, mais je dois prendre soin de plusieurs mots de passe pour le même nom d'utilisateur.

Voici le flux que je dois créer:

  1. Ouvrir une session TELNET sur une IP
  2. Envoyer un nom d'utilisateur
  3. Envoyer un mot de passe
  4. Mauvais mot de passe? Renvoyez le même nom d'utilisateur, puis un mot de passe différent
  5. Doit avoir réussi à se connecter à ce stade ...

Pour ce que ça vaut, voici ce que j'ai jusqu'à présent:

#!/usr/bin/expect
spawn telnet 192.168.40.100
expect "login:"
send "spongebob\r"
expect "password:"
send "squarepants\r"
expect "login incorrect" {
  expect "login:"
  send "spongebob\r"
  expect "password:"
  send "rhombuspants\r"
}
expect "Prompt\>" {
  send_user "success!\r"
}
send "blah...blah...blah\r"

Inutile de dire que cela ne fonctionne pas et que cela n'a pas l'air très joli. De mes aventures avec Google attendez semble être quelque chose d'un art sombre. Merci d'avance à tous pour votre aide en la matière!

25
shuckster

Doit recommenter le livre Exploring Expect pour tous les programmeurs attendus - inestimable.

J'ai réécrit votre code: (non testé)

proc login {user pass} {
    expect "login:"
    send "$user\r"
    expect "password:"
    send "$pass\r"
}

set username spongebob 
set passwords {squarepants rhombuspants}
set index 0

spawn telnet 192.168.40.100
login $username [lindex $passwords $index]
expect {
    "login incorrect" {
        send_user "failed with $username:[lindex $passwords $index]\n"
        incr index
        if {$index == [llength $passwords]} {
            error "ran out of possible passwords"
        }
        login $username [lindex $passwords $index]
        exp_continue
    }
    "Prompt>" 
}
send_user "success!\n"
# ...

exp_continue revient au début du bloc expect - c'est comme une instruction "redo".

Notez que send_user se termine par \n ne pas \r

Vous n'avez pas à échapper au > caractère dans votre invite: ce n'est pas spécial pour Tcl.

38
glenn jackman

Avec un peu de dénigrement, j'ai trouvé une solution. Il s'avère que expect utilise une syntaxe TCL que je ne connais pas du tout:

#!/usr/bin/expect
set pass(0) "squarepants"
set pass(1) "rhombuspants"
set pass(2) "trapezoidpants"
set count 0
set Prompt "> "
spawn telnet 192.168.40.100
expect {
  "$Prompt" {
    send_user "successfully logged in!\r"
  }
  "password:" {
    send "$pass($count)\r"
    exp_continue
  }
  "login incorrect" {
    incr count
    exp_continue
  }
  "username:" {
    send "spongebob\r"
    exp_continue
  }
}
send "command1\r"
expect "$Prompt"
send "command2\r"
expect "$Prompt"
send "exit\r"
expect eof
exit

J'espère que cela sera utile aux autres.

11
shuckster