Wie führe ich Sudo-Befehle mit Expect & Send-Befehlen im Bash-Skript aus?


10

Kann mir jemand mitteilen, wie sudoBefehle ausgeführt werden sollen expect? Ich habe Folgendes versucht, aber das funktioniert nicht. Kann mir bitte jemand einen Vorschlag machen?

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

Als ich das folgende Skript ausprobiert habe, wurde es fehlerfrei ausgeführt, aber ich habe die Ausgabe nicht erhalten. Hier ist das Skript und die Ausgabe, wenn es ausgeführt wird. Wo mache ich hier einen Fehler?

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

Ausführung

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

Antworten:


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 (und im weiteren Sinne erwarten) verhalten sich geschweifte Klammern wie die einfachen Anführungszeichen der Shell: Hemmung der variablen Expansion.

Die Erwartungsform mit mehreren Mustern ist nützlich für den Fall, dass Sie möglicherweise kein Muster sehen. Die exp_continueAnweisung "schleift" im Wesentlichen innerhalb der Erwartung, sodass Sie das Kennwort senden und die Eingabeaufforderung weiterhin erwarten können. Da dem Eingabeaufforderungsmuster keine Aktion zugeordnet ist, wechselt die Steuerung vom Befehl "Wechseln" zum nächsten.

Ich würde empfehlen, dies als separates Skript zu speichern. Erste Zeile sollte sein

#!/usr/bin/expect -f

Wenn Sie in ein Shell-Skript einbetten möchten:

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

Beachten Sie die Anführungszeichen um das erste "ENDE" - dies hat den Effekt, dass das gesamte Dokument hier in einfache Anführungszeichen gesetzt wird, sodass Sie sich keine Gedanken über die Shell machen müssen, die die Expect-Variablen interpretiert


Hallo Glenn, das Skript wird ohne Fehler ausgeführt, aber ich kann die Ausgabe des Scirpt nicht sehen. Mache ich irgendetwas falsch im Skript? Wenn ja, lassen Sie es mich bitte wissen. Ich speichere die Ausgabe in einer separaten Datei. Hier ist das Skript, das ich sasuke @ njob ausführe: ~ $ ./hypr.sh spawn ssh sasuke @ hostname sasuke @ hostname Passwort: sasuke @ hostname: ~ $ output = $ (sudo virsh list --all | awk '/ running / {print $ 2} '| tail -10) sudo virsh dominfo' $ output 'sasuke @ njob: ~ $
sasuke

Sie können keinen Code in Kommentaren posten, bitte fügen Sie ihn in Ihre Frage ein
Glenn Jackman

Oh, das tut mir leid. Danke, ich habe es geschafft. Bitte hilf mir.
Sasuke

Weiß nicht. Fügen Sie exp_internal 1oben im Skript hinzu und lesen Sie die ausführliche Ausgabe.
Glenn Jackman

3

Ich möchte meinen Scirpt teilen. Ich habe das auf meinem System versucht. das funktioniert gut.

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

Versuchen Sie, es mit dem Befehl "Interact" zu beenden, damit es funktioniert.

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

0

Ich denke, Sie müssen möglicherweise die Anführungszeichen innerhalb der Anführungszeichen zurücksetzen. Andernfalls wird expectder Befehl nach "awk" beendet:

send "output=$(sudo virsh list --all | awk \"/running/{print \$2}\" | tail -2); sudo virsh dominfo $output"
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.