使用 Expect 通过 SSH 管理机器,但不能完成所有任务
*请不要告诉我只使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用 Expect 来完成此类事情通常是错误的方法。
正确的方法是设置 ssh 密钥,以便您可以在远程计算机上进行 ssh 并运行命令,而无需提供密码。具体方法如下:
这是一个脚本,可以一次性执行上述操作:
http://jakehofman.com/ code/sshkey
然后,您可以像这样在远程计算机上运行命令:
但是,要使用 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:
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:
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.
事实证明,它提前退出的原因是我匹配的提示模式不仅匹配提示,还匹配我正在运行的 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.