3

*请不要堆积并告诉我只使用 SSH 密钥。如果它让你觉得这就是我正在做的事情,请假装我正在尝试远程登录。:-) *

我正在使用期望脚本通过 ssh 在我控制的一组服务器上运行一些常规命令。该脚本应该在每台机器上运行一组命令(例如 svn update ~/folderx\r")。我当前的脚本会执行我想要它做的所有事情......有时。其他时候它会在完成之前退出 ssh 连接最后几个命令。

关于如何使连接保持直到所有命令完成的任何想法?下面的代码成功登录,成功运行前两个命令左右(ap-get update 和其中一个 svn 更新),然后断开连接。

#!/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 密钥,这样您就可以在远程计算机上 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

It turns out that the reason it was exiting earlier was that the prompt pattern that I was matching against matched not only the prompt, but also some of the output from the svn commands I was running. I was matching against only the "username" portion of the prompt pattern (the prompt form was "username@machine:~$"). Once I altered the script to match only "username@" it began to work as expected.

p.s. the ssh script that dreeves links to above works very nicely.

于 2010-07-14T11:10:56.217 回答