bash e espera no mesmo script?

9

Estou tentando codificar um script que usa endereços IP de um arquivo .csv e telnet o dispositivo para capturar a saída do comando "show version".

Até agora eu codifiquei isso:

#!/bin/bash
#!/usr/bin/expect -f
FILE1=dispositivos.csv  #file with IP's and device name
set Username "user"    #this is the user for telnet connection.
set Password "this.is.the.pass"  #pass for telnet connection.

NUMERODISP="$(wc -l $FILE1 | awk '{print $1}')" #this command counts number of devices (IP's) in the file as it is a .csv file, it only counts number of lines.


for i in `seq 2 $NUMERODISP`; 
        do
    IP="$(awk -vnum="$i" 'NR == num { print $NF }' dispositivoss.csv)"
        echo "$IP" #this takes the IP from last column from .csv file
    done    

Eu preciso concluir o loop for para conectar-se via telnet ao IP armazenado em $ IP e salvar a saída "show version".

Eu tentei com isso:

for i in `seq 2 $NUMERODISP`;
        do
    IP="$(awk -vnum="$i" 'NR == num { print $NF }' dispositivoss.csv)"
        send "telnet $IP\r"
    expect "Username:"
    send "$Username\r"
    expect "Password: "
    send "$Password\r"
    expect "*>"
    send "show version\r"
    log_file -noappend SN_$IP.dat;
    expect -ex "--More--" {send -- " "; exp_continue}
    expect "*>"
    log_file;
    done    

mas não funcionou.

É por isso que não posso usar o bash e esperar?

Caso esse seja o motivo .. como posso enviar $ IP e $ NUMDISP como uma variável para um script de expectativa diferente? (é por isso que acho que é diferente da outra pergunta)

Alejandro Cesar Villegas Yepez
fonte
2
Não misturar as línguas, expectpode ler um arquivo CSV, como eu mostrei no unix.stackexchange.com/questions/350338/...
thrig
1
Possível duplicata da conexão múltipla de telnet em Expect while loop
thrig
@ Thrig o OP, obviamente, não sente que isso é um estúpido, uma vez que eles acabaram de fazer esta pergunta.
terdon
Fiz as duas perguntas, acho que isso é um pouco diferente do outro.
Cesar Alejandro Villegas Yepez

Respostas:

13
#!/bin/bash
#!/usr/bin/expect -f

Umm não.

Basicamente, você deseja que ambos os programas leiam seu script e "façam a coisa certa" em todas as linhas. Além dos problemas entre sincronizar a execução do script entre os intérpretes, é fácil ver que isso é impossível no momento em que temos uma linha que poderia ser um comando válido em qualquer idioma.

Considere algo como isto em seu exemplo.

set Username "user" 

Na verdade, é válido no shell e no script de expectativa. No shell, ele define os parâmetros posicionais $1e $2para Usernamee user, respectivamente. Em expectatribui outra coisa. Qual deles deve fazer?

Divida o script de espera em um arquivo diferente e chame-o do script de shell ou use o fato de o Expect ser executado no TCL, o que deve permitir fazer loops e E / S por si só.


Felizmente, neste caso, há apenas um trecho de expectativa contido em um loop de shell no seu segundo bloco de código.

Então, faça um script de shell

#!/bin/bash
for i in `seq 2 $NUMERODISP`; do
    IP="$(...)"
    expect -f somename.expect $IP
done

e um script esperado para chamar do shell script:

#!/usr/bin/expect -f 
set IP   [lindex $argv 0];
spawn telnet $IP
expect "Username:"
send "$Username\r"
...
ilkkachu
fonte
1
@cesar, existem maneiras de colocar um script esperado dentro de um script shell, mas sempre há dores de cabeça em torno de aspas e variáveis. Esta é a maneira mais limpa.
Glenn Jackman