スクリプトを使用して、いくつかの .deb パッケージの展開を自動化しようとしています。SSHsudo dpkg -i $myDeb.deb
でアクセスできるリモート マシンのリストで実行したいと考えています。
私は、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 コマンドをローカルで実行しようとしているようです (最初に '$remoteMachine' に ssh(s) し、次に sudo dpkg をローカルで実行します。これは 2 つの別々のコマンドのようです)
これとともに:
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 つのレベルの引用符を使い分ける必要がなくなると、自然に正しいコマンドを記述できるようになります。