3

*Please do not pile on and tell me to just use SSH keys. If it bugs you that this is the way I am doing it, pretend that I am trying to telnet in instead. :-) *

I am using an expect script to run some routine commands on a set of servers under my control via ssh. The script should run set of commands (eg svn update ~/folderx\r") on each of the machines. My current script does everything I want it to do... sometimes. Other times it exits the ssh connection before it completes one of the last few commands.

Any thoughts on how I can make the connection stay until all of the commands are completed? The code below successfully logs on, successfully runs the first two commands or so (ap-get update and one of the svn updates) and then disconnects.

#!/usr/bin/expect -f

spawn ssh username@ipaddress
set timeout -1
expect "Are you sure you want to continue connecting" {send "yes\r"; exp_continue} "password:" {send "*******\r"; exp_continue
    } "username@machine" {send "sudo apt-get update\r"}
expect "password" {send "*******\r"; exp_continue} "username@machine" {send "sudo svn update ~/folder1\r"}
expect "password" {send "*******\r"; exp_continue} "username@machine" {send "sudo svn update ~/folder2\r"}
expect "password" {send "*******\r"; exp_continue} "username@machine" {send "sudo svn update ~/folder3\r"}
expect "password" {send "*******\r"; exp_continue} "username@machine" {send "sudo reboot\r"}
close
4

2 に答える 2

3

一般に、Expect を使用することは、この種のことを行うには間違った方法です。正しい方法は、ssh キーをセットアップして、パスワードを入力せずにリモート マシンでコマンドを実行できるようにすることです。その方法は次のとおりです。

0. Create public/private key pair on local machine.
   (Only needs to be done once on local machine for all remote machines.)
   Go to the ~/.ssh directory on your local machine and do this:
   % ssh-keygen -t rsa
1. Copy the public key to the remote machine:
   % scp ~/.ssh/id_rsa.pub you@foo.com:.
2. Append that key to the authorized_keys file on the remote machine:
   % ssh you@foo.com 'cat id_rsa.pub >> .ssh/authorized_keys; /bin/rm id_rsa.pub'
3. Finally, in case it doesn't work, check permissions, which must be just so: 
   (or maybe it's just that they can't be group/world writeable)
   % cd ~; ls -ld . .ssh .ssh/authorized_keys
     drwxr-xr-x  .
     drwxr-xr-x  .ssh
     -rw-r--r--  .ssh/authorized_keys

上記を一気に実行するスクリプトを次に示します。

http://jakehofman.com/code/sshkey

その後、次のようにリモート マシンでコマンドを実行できます。

ssh alice@remote.com ./foo args

ただし、sudo を使用してリモート マシンでコマンドを実行する場合は、別の話かもしれません。うまくいけば、他の人がそれについてチャイムを鳴らすことができます. ただし、最初のステップとして、最初のログインで Expect を使用しないようにする必要があります。

于 2010-07-12T19:45:23.113 に答える
2

以前に終了していた理由は、照合していたプロンプト パターンが、プロンプトだけでなく、実行していた svn コマンドからの出力の一部にも一致したためであることが判明しました。プロンプト パターンの「ユーザー名」部分のみと照合していました (プロンプト フォームは「username@machine:~$」でした)。「username@」のみに一致するようにスクリプトを変更すると、期待どおりに機能し始めました。

ps 上記へのリンクを作成する ssh スクリプトは非常にうまく機能します。

于 2010-07-14T11:10:56.217 に答える