我正在嘗試使用腳本自動部署一些 .deb 套件。我想在sudo dpkg -i $myDeb.deb
可以透過 ssh 存取的遠端電腦清單中執行。
我嘗試在 bash 腳本中使用“expect”自動執行命令,但顯然我做錯了一些事情,因為我收到了許多不同的錯誤(基本上取決於我放置引號的位置)
這是我擁有的函數(將使用以下內容呼叫:_remoteInstallation "myPackage115.deb" "192.168.1.55"
。我知道在遠端電腦中,.deb 將位於 $HOME/Documents/ 中:
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
}
透過像這樣的生成區域中的引號,我得到
expect: invalid option -- 't'
如果我把它改成:
spawn /usr/bin/ssh -t borrajax@$remoteMachine '/usr/bin/sudo /usr/bin/dpkg -i /home/borrajax/Documents/$debToInstall'
看起來正在嘗試在本地運行 sudo dpkg 命令(首先 ssh 到“$remoteMachine”,然後在本地運行 sudo dpkg,就像兩個單獨的命令)
有了這個:
spawn '/usr/bin/ssh -t borrajax@$remoteMachine \'/usr/bin/sudo /usr/bin/dpkg -i /home/borrajax/Documents/$debToInstall\''
我明白了couldn't execute "'/usr/bin/ssh": no such file or directory
(這不是真的)
....此時,我已經沒有想法了......:-)
任何提示將不勝感激。謝謝。
答案1
我認為您錯過了一定程度的引號轉義。在這種高層次的轉義中,最好為每個階段簡單地製作一個小腳本,否則需要引用。
否則,您可以嘗試這個修改版本(但請注意,我不鼓勵這種編碼風格!)
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
}
答案2
為什麼人們總是用這種醜陋的expect
東西ssh
?使用 ssh 金鑰就可以了(閱讀公鑰密碼學的理論,一勞永逸ssh-copy-id remotemachine
的練習)。然後使用就很簡單了
ssh remote-machine "remote-shell-command" > local-redirection-of-command-output
一旦您不必在 3 個層級的引用之間切換,您自然會編寫正確的命令。