Explicador de scripts Expect
Cole um script Expect e leia o que ele faria, comando por comando: o que inicia (spawn), o que espera, o que digita, quando passa o teclado a você. Depois, o diálogo que conduz e os achados: uma senha em texto claro, um timeout deixado no padrão ou infinito, um padrão que casa cedo demais, um send sem o retorno que o programa espera, um script que termina antes de o programa responder. Analisado com o motor Tcl 8.4, nunca executado; cada regra cita o manual expect(1).
Texto e utilitáriosO Tcl consegue lê-lo. 1 erro, 1 aviso, 4 notas.
11 linhas, 9 comandos. Inicia telnet. Timeout no primeiro expect: o padrão, 10 segundos. Nunca espera o programa terminar.
O diálogo
| nº | linha | espera por | então digita |
|---|---|---|---|
| 1 | 3 | login: | admin\r |
| 2 | 5 | Password: | •••••••• |
| 3 | 7 | > | terminal length 0\r |
| 4 | 9 | > | show running-config\r |
Comando por comando
- 1
#!/usr/bin/expectRoda sob
/usr/bin/expect: a primeira linha nomeia o interpretador; para o Tcl é um comentário. - 2
spawn telnet 10.0.0.1Inicia
telnetcom10.0.0.1como processo atual. Daqui em diante, expect lê a saída dele e send digita nele. - 3
expect "login:"Espera a saída do programa casar: um padrão.
login:
- 4
send "admin\r"Digita
admin\rno programa, terminando com um retorno. - 5
expect "Password:"Espera a saída do programa casar: um padrão.
Password:
- 6
send "Cisco123\r"Digita
Cisco123\rno programa, terminando com um retorno. - 7
expect ">"Espera a saída do programa casar: um padrão.
>
- 8
send "terminal length 0\r"Digita
terminal length 0\rno programa, terminando com um retorno. - 9
expect ">"Espera a saída do programa casar: um padrão.
>
- 10
send "show running-config\r"Digita
show running-config\rno programa, terminando com um retorno.
O script, com as linhas marcadas
Achados
- notaE2linha 3Timeout
expect "login:"Nenhum timeout foi definido antes deste expect, então vale o padrão de 10 segundos (expect(1)). Logins lentos e comandos longos precisam de mais; diga o que quer com set timeout.
- notaE7linha 3Sem tratamento de timeout
expect "login:"4 expects esperam por um padrão sem tratamento de timeout. Quando o padrão não chega a tempo, o expect(1) executa uma ação nula implícita: o expect retorna em silêncio e o script segue como se tivesse casado, digitando comandos para um programa que não está onde o script pensa. Acrescente um padrão timeout que avise e saia.
- erroE1linha 6Segredo em texto claro
send "Cisco123\r"Um segredo digitado em texto claro: logo após um prompt de senha, o script envia ••••••••, escrito no arquivo. Quem puder ler o script lê a senha. Tome-a da linha de comando (lindex $argv), do ambiente ($env(NOME)) ou peça-a com stty -echo e expect_user.
- notaE3linha 7Padrão que casa cedo demais
expect ">"Um padrão de um só caractere, >. Os padrões não são ancorados e casam em qualquer ponto da saída, então um banner ou uma linha anterior que contenha esse caractere encerra a espera antes da hora. Case mais do prompt e ancore uma regexp com $ (o expect(1) recomenda quando se pode descrever o fim da cadeia).
- notaE3linha 9Padrão que casa cedo demais
expect ">"Um padrão de um só caractere, >. Os padrões não são ancorados e casam em qualquer ponto da saída, então um banner ou uma linha anterior que contenha esse caractere encerra a espera antes da hora. Case mais do prompt e ancore uma regexp com $ (o expect(1) recomenda quando se pode descrever o fim da cadeia).
- avisoE4linha 10Termina em um send
send "show running-config\r"O último ato do script é um send. Quando o script termina, o Expect fecha as conexões com os processos iniciados (expect(1)); o que o programa imprimir em resposta nunca é lido, e o programa pode não ter terminado. Termine com expect eof, um expect pelo prompt final ou interact.
O explicador lê o texto do script e nunca o executa. Segue os corpos de expect, if, foreach, while, for, switch, catch e proc na ordem do fonte, por isso não sabe qual ramo uma execução toma, quantas vezes um loop roda ou se um procedimento chega a ser chamado. Padrões e cadeias que dependem de uma variável aparecem como escritos. Cada fato sobre o Expect vem do expect(1), citado em Fontes.