使用 Expect 通过 SSH 管理机器,但不能完成所有任务

发布于 2024-09-09 00:25:09 字数 991 浏览 13 评论 0原文

*请不要告诉我只使用 SSH 密钥。如果我这样做让您感到烦恼,请假装我正在尝试远程登录。 :-) *

我正在使用 Expect 脚本通过 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

*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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜柠檬 2024-09-16 00:25:09

使用 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 [email protected]:.
2. Append that key to the authorized_keys file on the remote machine:
   % ssh [email protected] '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 [email protected] ./foo args

但是,要使用 sudo 在远程计算机上运行命令,可能是另一回事了。
希望其他人能够对此发表意见。
但作为第一步,您应该避免首次登录时使用 Expect。

Using Expect is generally the wrong way to do this kind of thing.
The right way is to set up ssh keys so that you can ssh and run commands on the remote machine without supplying a password. Here's how to do that:

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 [email protected]:.
2. Append that key to the authorized_keys file on the remote machine:
   % ssh [email protected] '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

Here's a script that does the above in one fell swoop:

http://jakehofman.com/code/sshkey

You can then run commands on the remote machine like so:

ssh [email protected] ./foo args

To run commands on the remote machine with sudo, however, may be another story.
Hopefully others can chime in about that.
But as a first step you should avoid Expect for the initial login.

一身仙ぐ女味 2024-09-16 00:25:09

事实证明,它提前退出的原因是我匹配的提示模式不仅匹配提示,还匹配我正在运行的 svn 命令的一些输出。我仅匹配提示模式的“用户名”部分(提示形式为“username@machine:~$”)。一旦我将脚本更改为仅匹配“用户名@”,它就开始按预期工作。

ps dreeves 链接到上面的 ssh 脚本运行得非常好。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文