Ich versuche, die Bereitstellung einiger .deb-Pakete mit einem Skript zu automatisieren. Ich möchte es sudo dpkg -i $myDeb.deb
in 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 expect
Zeug 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 remotemachine
ein 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.