Como executar comandos sudo com esperar e enviar comandos no script bash?

10

Alguém pode me informar como executar sudocomandos expect? Eu tentei o seguinte, mas isso não está funcionando. Alguém pode me dar 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 tentei 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 $2}' | 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 $2}' | tail -10)sudo virsh dominfo '$output' sasuke@njob:~$
sasuke
fonte

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 $2}' | 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, espere), os chavetas agem como as aspas simples do shell: inibem a expansão variável.

A forma de expectativa com vários padrões é útil para o caso em que você pode não ver um padrão. A exp_continueinstrução basicamente "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 recomendaria que você salve isso como um script separado. A primeira linha deve ser

#!/usr/bin/expect -f

Se você deseja incorporar 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 citar o documento aqui inteiro para que você não precise se preocupar com o fato de o shell interpretar as variáveis ​​Expect

Glenn Jackman
fonte
Oi Glenn, o script está sendo executado sem erros, mas não consigo ver a saída do scirpt. Estou fazendo alguma coisa errada no script. Se sim, por favor me avise que eu salve a saída em arquivo separado. Aqui está o script que estou executando: sasuke @ njob: ~ $ ./hypr.sh spawn ssh sasuke @ nome do host sasuke @ senha do nome do host: sasuke @ nome do host: ~ $ output = $ (lista de sudo virsh - tudo | awk '/ executando / {print $ 2} '| tail -10) sudo virsh dominfo' $ output 'sasuke @ njob: ~ $
sasuke
Você pode código não pós em comentários, por favor, adicioná-lo na sua pergunta
glenn jackman
Oh, desculpe por isso. Graças eu fiz isso. Por favor, me ajude.
usar o seguinte
Não sei. Adicione exp_internal 1à parte superior do script e leia a saída detalhada.
Glenn Jackman
3

Eu gostaria de compartilhar meu acerto. 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"
sasuke
fonte
1

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
Ravan
fonte
0

Acho que você pode precisar fazer uma barra invertida nas aspas. Caso contrário, expectpensa que o comando termina após "awk":

send "output=$(sudo virsh list --all | awk \"/running/{print \$2}\" | tail -2); sudo virsh dominfo $output"
Paulo
fonte