Comment exécuter les commandes sudo avec les commandes Expect & send dans le script bash?

10

Quelqu'un peut-il me faire savoir comment exécuter des sudocommandes avec expect? J'ai essayé ce qui suit mais cela ne fonctionne pas. Quelqu'un peut-il me donner une suggestion s'il vous plaît?

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

Lorsque j'ai essayé le script ci-dessous, il s'est exécuté sans erreur, mais je n'ai pas obtenu la sortie. Voici le script et la sortie lors de son exécution. Où est-ce que je fais une erreur ici?

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

Exécution

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
la source

Réponses:

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

Dans Tcl (et, par extension, attendez-vous), les accolades agissent comme les guillemets simples du shell: inhibent l'expansion variable.

La forme d'attente à plusieurs modèles est utile dans le cas où vous ne pouvez pas voir un modèle. L' exp_continueinstruction "boucle" essentiellement dans l'attente afin que vous puissiez envoyer le mot de passe et continuer à attendre l'invite. Puisqu'aucune action n'est associée au modèle d'invite, le contrôle passe de la commande expect à la suivante.

Je vous recommande de l'enregistrer en tant que script séparé. La première ligne doit être

#!/usr/bin/expect -f

Si vous souhaitez intégrer un script shell:

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

Notez les guillemets autour du premier "END" - ce qui a pour effet de guillemet unique l'ensemble du document ici afin que vous n'ayez pas à vous soucier du shell interprétant les variables Expect

glenn jackman
la source
Salut Glenn, le script s'exécute sans erreur, mais je ne peux pas voir la sortie du scirpt. Suis-je en train de faire quelque chose de mal dans le script. Si oui, faites-le moi savoir, j'enregistre la sortie dans un fichier séparé. voici le script que j'exécute sasuke @ njob: ~ $ ./hypr.sh spawn ssh sasuke @ hostname sasuke @ hostname mot de passe: sasuke @ hostname: ~ $ output = $ (sudo virsh list --all | awk '/ en cours d'exécution / {print $ 2} '| tail -10) sudo virsh dominfo' $ output 'sasuke @ njob: ~ $
sasuke
Vous ne pouvez pas poster de code dans les commentaires, veuillez l'ajouter dans votre question
glenn jackman
oh je suis désolé pour ça. Merci je l'ai fait. Sil te plait aide moi.
sasuke
Je ne sais pas. Ajoutez exp_internal 1en haut du script et lisez la sortie détaillée.
glenn jackman
3

Je voudrais partager mon scirpt. J'ai essayé cela sur mon système. cela fonctionne 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"
sasuke
la source
1

Essayez de le terminer avec la commande "interact", cela devrait fonctionner.

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

Je pense que vous devrez peut-être annuler les guillemets dans les guillemets. Sinon, expectpense que la commande se termine après "awk":

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