¿Cómo ejecutar comandos sudo con Expect y enviar comandos en bash script?


10

¿Alguien puede decirme cómo ejecutar sudocomandos expect? Intenté lo siguiente pero esto no funciona. ¿Alguien puede darme una sugerencia 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 "#"

Cuando probé el siguiente script, se ejecutó sin errores, pero no obtuve el resultado. Aquí está el script y la salida cuando se ejecuta. ¿Dónde estoy cometiendo un error aquí?

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

Ejecución

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

Respuestas:


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

En Tcl (y, por extensión, esperar), las llaves se comportan como comillas simples del shell: inhiben la expansión variable.

La forma multipatrón de esperar es útil para el caso en el que no puede ver un patrón. La exp_continuedeclaración esencialmente "se repite" dentro de lo esperado para que pueda enviar la contraseña y continuar esperando la solicitud. Como no hay ninguna acción asociada con el patrón de solicitud, el control pasa del comando esperar al siguiente.

Te recomendaría guardar esto como un script separado. La primera línea debería ser

#!/usr/bin/expect -f

Si desea incrustar en un script de shell:

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

Tenga en cuenta las comillas alrededor del primer "FIN", que tiene el efecto de una sola cita de todo el documento aquí para que no tenga que preocuparse de que el intérprete interprete las variables Esperar


Hola Glenn, el script se está ejecutando sin errores, pero no puedo ver la salida del scirpt. ¿Estoy haciendo algo mal en el guión? En caso afirmativo, avíseme si guardo la salida en un archivo separado. aquí está el script que estoy ejecutando sasuke @ njob: ~ $ ./hypr.sh spawn ssh sasuke @ hostname sasuke @ hostname's password: sasuke @ hostname: ~ $ output = $ (sudo virsh list --all | awk '/ corriendo / {print $ 2} '| tail -10) sudo virsh dominfo' $ output 'sasuke @ njob: ~ $
sasuke

No puede publicar el código en los comentarios, agréguelo a su pregunta
glenn jackman

Oh lo siento por eso. Gracias lo hice. Por favor, ayúdame.
sasuke

No se Agregue exp_internal 1a la parte superior de la secuencia de comandos y lea la salida detallada.
Glenn Jackman

3

Me gustaría compartir mi scirpt. Intenté esto en mi sistema. Esto está funcionando bien.

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

Intente finalizarlo con el comando "interactuar", debería funcionar.

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

0

Creo que es posible que necesite hacer una barra diagonal inversa entre comillas. De lo contrario, expectpiensa que el comando termina después de "awk":

send "output=$(sudo virsh list --all | awk \"/running/{print \$2}\" | tail -2); sudo virsh dominfo $output"
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.