SSH + Sudo + Expect im Bash-Skript: Befehl mit sudo auf Remotecomputer ausführen

SSH + Sudo + Expect im Bash-Skript: Befehl mit sudo auf Remotecomputer ausführen

Ich versuche, die Bereitstellung einiger .deb-Pakete mit einem Skript zu automatisieren. Ich möchte es sudo dpkg -i $myDeb.debin einer Liste von Remote-Rechnern ausführen, auf die ich per SSH zugreifen kann.

Ich habe versucht, den Befehl mit „expect“ in einem Bash-Skript zu automatisieren, aber ich mache offensichtlich etwas falsch, da ich eine Reihe unterschiedlicher Fehler erhalte (im Wesentlichen abhängig davon, wo ich die Anführungszeichen setze).

Dies ist die Funktion, die ich habe (wird mit etwas wie diesem aufgerufen: _remoteInstallation "myPackage115.deb" "192.168.1.55". Ich weiß, dass sich die .deb-Datei auf dem Remotecomputer in $HOME/Documents/ befindet:

function _remoteInstallation(){
    local retval=1
    local debToInstall=$(basename "$1")
    local remoteMachine="$2"
    spawned=$(expect -d -c "
          set timeout 1800
          spawn "/usr/bin/ssh -t borrajax@$remoteMachine /usr/bin/sudo /usr/bin/dpkg -i /home/borrajax/Documents/$debToInstall"'
          expect {
                \"Are you sure you want to continue connecting\" { send \"yes\r\"; exp_continue }
                \"password\" { send \"myPassword\r\";  exp_continue }
                \"[sudo] password\" { send \"myPassword\r\";  exp_continue }
                default { exit 1 }
          }
    " )
    retval=$?
    return $retval
}

Mit den Anführungszeichen im erzeugten Bereich wie diesen bekomme ich

expect: invalid option -- 't'

Wenn ich es ändere in:

 spawn /usr/bin/ssh -t borrajax@$remoteMachine '/usr/bin/sudo /usr/bin/dpkg -i /home/borrajax/Documents/$debToInstall'

Es sieht so aus, als würde versucht, den Befehl „sudo dpkg“ lokal auszuführen (zuerst per SSH zu „$remoteMachine“ und dann lokal „sudo dpkg“ ausführen, also wie zwei separate Befehle).

Mit diesem:

spawn '/usr/bin/ssh -t borrajax@$remoteMachine \'/usr/bin/sudo /usr/bin/dpkg -i /home/borrajax/Documents/$debToInstall\''

Ich verstehe das couldn't execute "'/usr/bin/ssh": no such file or directory(was nicht stimmt)

... und an diesem Punkt gingen mir die Ideen aus ...:-)

Jeder Hinweis ist willkommen. Vielen Dank.

Antwort1

Ich glaube, Sie haben eine Ebene der Anführungszeichen-Entfernung übersehen. Bei dieser hohen Entfernungsebene ist es am besten, einfach für jede Stufe, in der sonst Anführungszeichen erforderlich wären, ein kleines Skript zu erstellen.

Andernfalls könnten Sie diese modifizierte Version ausprobieren (aber beachten Sie, dass ich diesen Codierstil nicht empfehle!)

function _remoteInstallation(){
    local retval=1
    local debToInstall=$(basename "$1")
    local remoteMachine="$2"
    spawned=$(expect -d -c "
          set timeout 1800
          spawn \"/usr/bin/ssh -t borrajax@$remoteMachine /usr/bin/sudo /usr/bin/dpkg -i /home/borrajax/Documents/$debToInstall\"
          expect {
                \"Are you sure you want to continue connecting\" { send \"yes\r\"; exp_continue }
                \"password\" { send \"myPassword\r\";  exp_continue }
                \"[sudo] password\" { send \"myPassword\r\";  exp_continue }
                default { exit 1 }
          }
    " )
    retval=$?
    return $retval
}

Antwort2

Warum verwenden die Leute immer dieses hässliche expectZeug mit ssh? Verwenden Sie SSH-Schlüssel und Sie sind fertig (lesen Sie die Theorie über Public-Key-Kryptographie, verwenden Sie sie einfach ssh-copy-id remotemachineein für alle Mal zur Praxis). Dann ist die Verwendung so einfach wie

ssh remote-machine "remote-shell-command" > local-redirection-of-command-output

Sobald Sie nicht mehr zwischen 3 Zitierebenen jonglieren müssen, werden Sie ganz selbstverständlich korrekte Befehle schreiben.

verwandte Informationen