Obtém a saída do script expect em uma variável

2

Eu tenho um script de espera que fornece o endereço IP:

#!/bin/expect -f
set nodename [lindex $argv 0]
spawn virsh console $nodename
expect "Escape character is"
send "\n"
expect "localhost login: " {
    send "root\n"
    expect "Password: "
    send "cloud123\n"
}
expect "~]#" {
        send "\n"
        send "ifconfig | grep 192.168.1. | awk \'{print \}\'"
        send "\n"
        expect '(\d+\.\d+\.\d+\.\d+)'
        send "logout"
}

Eu quero que o script retorne esse endereço IP. Eu estou chamando esse script de espera de um script de shell como abaixo

#!/bin/bash
ip=$(expect GetIP.exp nodetwo)
echo $ip

Como posso fazer com que meu script de retorno retorne a saída para o script de shell?

    
por karan ratnaparkhi 28.10.2015 / 09:47

1 resposta

2

OK, ligar e desligar o log não funcionou - problemas de tempo, provavelmente.

O script de expectativa abaixo funcionou para mim quando chamado assim

# ip=$(./virsh-expect nodetwo | tr -d '\r' | grep '^192.168')
# echo $ip 
192.168.122.99

O importante a ser observado aqui é que os retornos de carro são removidos da saída com tr e grepping para o IP aqui no script de shell. O script expect nem sequer tenta "esperar", apenas espera o próximo prompt do shell de root e sai.

Também tornei o script expect mais genérico - ele apenas espera "login:" em vez de "localhost login:" (que falharia em qualquer VM que realmente tivesse um nome de host ... e a maioria o faria) e uma planície "#" para o prompt do shell de root.

#!/usr/bin/expect -f
set nodename [lindex $argv 0]
spawn virsh console $nodename
expect "Escape character is"
send "\n\n"
expect "login: " {
    send "root\n"
    expect "Password: "
    send "cloud123\n"
}   
expect "# " {
        send "ifconfig | awk \'/192\.168/ {print \}\'"
        send "\n"
        expect "# "
        send "exit"
}

Outra alternativa é não usar expect , mas use Expect.pm do perl ou pexpect do python. Eles funcionam praticamente da mesma maneira que expect , mas facilitam a extração de dados da sessão de espera.

Ainda acho que há maneiras muito melhores de obter o endereço IP de uma VM do que usar expect on virsh console .

Aqui está uma maneira de fazer isso, que extrai o endereço MAC de virsh dumpxml e, em seguida, greps para a entrada dnsmasq-dhcp correspondente em /var/log/daemon.log using awk :

# mac=$(virsh dumpxml nodetwo | sed -n -e "/mac address/ s/.*'\([^']*\)'.*// p" | tail -1)
# ip=$(awk "/dnsmasq.*DHCPACK.*$mac/ {print \}" /var/log/daemon.log  | tail -1)
# echo $ip
192.168.122.99

No meu sistema, a VM tem duas interfaces de rede, e estou interessado apenas no último com essa finalidade, portanto, estou usando tail -1 na linha virsh dumpxml . A tail -1 na linha awk é para garantir que só recebamos a alocação dhcp mais recente para esse endereço MAC.

(na verdade, a VM com a qual testei no meu sistema é chamada de 'sid', não de 'nodetwo', mas editei a saída, bem como a senha no script de espera, para atender à sua pergunta. Também os endereços IP estou usando para minhas VMs são 192.168.122.x em vez de 192.168.1.x - mas isso é uma diferença trivial em detalhes)

Atualizar

Eu tive que usar isso na noite passada para encontrar o IP de um vbs freebsd que eu criei. Eu uso ISC dhcpd em vez de dnsmasq , então o formato do log é um pouco diferente. Esta versão funciona para dnsmasq e dhcpd :

$ cat find-vm-ip-by-name.sh
#!/bin/bash

mac=$(virsh dumpxml "$1" | sed -n -e "/mac address/ s/.*'\([^']*\)'.*// p" | tail -1)
ip=$(awk "/dnsmasq.*DHCPACK.*$mac/ {print \} ; /dhcpd.*DHCPACK.*$mac/ {print \}" /var/log/daemon.log  | tail -1)
echo $ip
    
por 28.10.2015 / 10:19