Bash 腳本中的 SSH + Sudo + Expect:在遠端電腦中使用 sudo 運行命令

Bash 腳本中的 SSH + Sudo + Expect:在遠端電腦中使用 sudo 運行命令

我正在嘗試使用腳本自動部署一些 .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 個層級的引用之間切換,您自然會編寫正確的命令。

相關內容