Como executar comandos sudo com os comandos Expect & send no script bash?

9

Alguém pode me informar como executar sudo comandos com expect ? Eu tentei o seguinte, mas isso não está funcionando. Alguém pode me dar uma sugestão, por favor?

set login "sasuke"
set addr "hostname"
set pw "mypasswd"
spawn ssh $login@$addr
expect "$login@$addr\'s password:"
send "$pw\r"
expect "#"
send "output=$(sudo virsh list --all | awk "/running/{print $2}" | tail -2); sudo virsh dominfo $output"
expect "password:"
send "$pw\r"
expect "#"

Quando experimentei o script abaixo, ele foi executado sem erros, mas não obtive a saída. Aqui está o script e a saída quando ele é executado. Onde estou cometendo um erro aqui?

set login "sasuke"
set addr "hostname"
set pw "mypasswd"
spawn ssh $login@$addr
expect "$login@$addr's password:"
send "$pw\r"
expect "#"
send {output=$(sudo virsh list --all | awk '/running/{print }' | tail -2)}
expect {
    password: {send "$pw\r"; exp_continue}
    "#"
}
send {sudo virsh dominfo "$output"}    ;# don't know if you need quotes there
expect {
    password: {send "$pw\r"; exp_continue}
    "#"
}

Execução

sasuke@njob:~$ ./hypr.sh 
spawn ssh sasuke@hostname 
sasuke@hostname's password: 
sasuke@hostname:~$ output=$(sudo virsh list --all | awk '/running/{print }' | tail -10)sudo virsh dominfo '$output' sasuke@njob:~$
    
por sasuke 12.06.2013 / 01:41

4 respostas

10
set login "sasuke"
set addr "hostname"
set pw "mypasswd"
spawn ssh $login@$addr
expect "$login@$addr's password:"
send "$pw\r"
expect "#"
send {output=$(sudo virsh list --all | awk '/running/{print }' | tail -2)}
expect {
    password: {send "$pw\r"; exp_continue}
    "#"
}
send {sudo virsh dominfo "$output"}    ;# don't know if you need quotes there
expect {
    password: {send "$pw\r"; exp_continue}
    "#"
}

No Tcl (e, por extensão, expect), chaves como as aspas simples do shell: inibem a expansão da variável.

A forma multi-padrão de esperar é útil para o caso em que você não pode ver um padrão. A instrução exp_continue essencialmente "faz um loop" dentro do esperado, para que você possa enviar a senha e continuar esperando o prompt. Como não há ação associada ao padrão de prompt, o controle passa do comando expect para o próximo.

Eu recomendo que você salve isso como um script separado. Primeira linha deve ser

#!/usr/bin/expect -f

Se você quiser incorporar em um script de shell:

#!/bin/sh
expect <<'END'
   # code as above
END

Observe as aspas ao redor do primeiro "END" - que tem o efeito de uma única citação de todo o documento aqui, assim você não precisa se preocupar com o shell interpretando as variáveis Esperadas

    
por glenn jackman 12.06.2013 / 03:13
3

Eu gostaria de compartilhar meu scirpt. Eu tentei isso no meu sistema. isso está funcionando bem.

#!/usr/bin/expect
set username "myname"
set password "mypasswd"
set hosts "hostname"
foreach line [split $ip \n] {
spawn ssh -o StrictHostKeyChecking=no $username@$hosts
expect "$username@$hosts's password:"
send -- "$password\n"
expect "$"
send -- "sudo virsh list|awk '{print $2}'|grep 'inmobi' >vm.list; for host in 'cat vm.list'; do sudo virsh dominfo $host >> vm.info; done\n"
expect "$"
send -- "$password\n"
expect "$"
send -- "exit\n"
    
por sasuke 18.06.2013 / 01:49
0

Acho que você pode precisar inverter as aspas entre aspas. Caso contrário expect acha que o comando termina depois de "awk":

send "output=$(sudo virsh list --all | awk \"/running/{print $2}\" | tail -2); sudo virsh dominfo $output"
    
por Paul 12.06.2013 / 02:54
0

Tente finalizá-lo com o comando "interagir" que deve funcionar.

spawn ssh -l $username $ip -p $sshport
sleep 5
expect "password:"
send "$pass\r"
interact
    
por Ravan 05.10.2016 / 18:35