SSH + Sudo + Expect в скрипте Bash: запуск команды с sudo на удаленной машине

SSH + Sudo + Expect в скрипте Bash: запуск команды с sudo на удаленной машине

Я пытаюсь автоматизировать развертывание некоторых пакетов .deb с помощью скрипта. Я хочу выполнить его sudo dpkg -i $myDeb.debв списке удаленных машин, к которым я могу получить доступ по ssh.

Я пытался автоматизировать команду с помощью «expect» внутри скрипта bash, но я, очевидно, делаю что-то неправильно, потому что получаю ряд различных ошибок (в зависимости от того, где я ставлю кавычки, в основном)

Вот какая у меня есть функция (она будет вызываться примерно так: ) _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(s) для '$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

Как только вам не придется жонглировать тремя уровнями цитирования, вы естественным образом начнете писать правильные команды.

Связанный контент