Come eseguire i comandi sudo con Expect e inviare comandi nello script bash?


10

Qualcuno può farmi sapere come eseguire i sudocomandi con expect? Ho provato quanto segue ma questo non funziona. Qualcuno può darmi suggerimenti per favore?

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 ho provato lo script seguente, è stato eseguito senza errori, ma non ho ottenuto l'output. Ecco lo script e l'output quando viene eseguito. Dove sto facendo un errore qui?

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}
    "#"
}

Esecuzione

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:~$

Risposte:


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}
    "#"
}

In Tcl (e, per estensione, aspettarsi), le parentesi graffe si comportano come le virgolette singole della shell: inibiscono l'espansione variabile.

La forma multi-pattern di wait è utile nel caso in cui potresti non vedere un pattern. L' exp_continueistruzione essenzialmente "scorre" all'interno dell'aspettativa in modo da poter inviare la password e continuare ad aspettarsi il prompt. Poiché non è presente alcuna azione associata al modello di prompt, il controllo passa dal comando di attesa a quello successivo.

Ti consiglierei di salvarlo come uno script separato. La prima riga dovrebbe essere

#!/usr/bin/expect -f

Se si desidera incorporare in uno script di shell:

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

Nota le virgolette intorno alla prima "END" - che ha l'effetto di virgolette singole sull'intero documento qui, quindi non devi preoccuparti che la shell interpreti le variabili Expect


Ciao Glenn, lo script viene eseguito senza errori, ma non riesco a vedere l'output dello script. Sto facendo qualcosa di sbagliato nella sceneggiatura. Se sì, per favore fatemi sapere che salvo l'output in file separato. ecco lo script che sto eseguendo sasuke @ njob: ~ $ ./hypr.sh spawn ssh sasuke @ hostname sasuke @ password hostname: sasuke @ hostname: ~ $ output = $ (sudo virsh list --all | awk '/ running / {print $ 2} '| tail -10) sudo virsh dominfo' $ output 'sasuke @ njob: ~ $
sasuke

Non puoi inserire codice nei commenti, per favore aggiungilo alla tua domanda
Glenn Jackman,

oh mi dispiace per quello. Grazie l'ho fatto. Per favore aiutatemi.
sasuke,

Non lo so. Aggiungi exp_internal 1all'inizio dello script e leggi l'output dettagliato.
Glenn Jackman,

3

Vorrei condividere il mio spirito. Ho provato questo sul mio sistema. sta funzionando bene.

#!/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"

1

Prova a terminarlo con il comando "interagisci" dovrebbe funzionare.

spawn ssh -l $username $ip -p $sshport
sleep 5
expect "password:"
send "$pass\r"
interact

0

Penso che potresti dover ricambiare le virgolette all'interno delle virgolette. Altrimenti expectpensa che il comando finisca dopo "awk":

send "output=$(sudo virsh list --all | awk \"/running/{print \$2}\" | tail -2); sudo virsh dominfo $output"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.