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

我解决类似问题的方法是将所有远程脚本放入一个文件中,例如/usr/local/bin/debinstall.sh。对于您的情况,我的建议是:有一个特殊的目录,将包放入其中——我们称之为/tmp/remoteinstall示例。此外,将您连接的用户放入/etc/suduers文件中,并允许其执行sudo dpkg -i *而无需提示输入密码。debinstall.sh然后看起来像这样:

#!/bin/bash
cd /tmp/remoteinstall
sudo dpkg -i *.deb && rm -f *

使该脚本归 和 拥有chmod 744 /usr/local/bin/debinstall.sh

在本地,你的工作只是上传你的 .deb 文件并调用脚本:

cd /path/to/files
scp * user@remotemachine:/tmp/remoteinstall
ssh user@remotemachine /usr/local/bin/debinstall.sh

debinstall.sh然后会安装你的软件包,然后清空目录仅当安装成功完成时

如果中缺少某些内容$PATH,请记住都不.bashrc.profile这样的执行方式 - 因此您可能需要在远程脚本的开头获取它们,或者在那里定义适当的 PATH。

相关内容