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

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


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"

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

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"
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.