用ruby的net/ssh链接远程的服务器

本文介绍了一种使用Ruby语言及Net::SSH库实现自动化SSH连接并执行远程命令的方法。通过自定义SSHConfig类来简化配置过程,利用Batch类批量执行命令,提高了工作效率。

最近用SSH比较多了,需要连接到一些远程的服务器上,然后执行一些命令。次数多了,渐渐就觉得比较麻烦。于是写了一个脚本用来让程序自动去执行一些重复的动作。

ruby下的SSH库最常用的是net/ssh。可以从它的网站去找一些信息。(http://net-ssh.rubyforge.org/)上面有一些例子,来告诉用户到底怎么使用这个东西。其实模式很简单,先是通过start方法链接到服务器,开启一个session,然后在这个session的上下文上去用exec方法执行一些命令。当然还有更复杂一些的用法,不过鉴于需求只是执行命令,那么复杂的东西就放一放。

如果你愿意,每写一个脚本都用Net::SSH.start(...)开头可以,不过这个看上去并不方便。至少打的字还是比较多的。那就封装一下吧。其实怎么对这些库进行封装是仁者见仁智者见智的事情。我的想法是抽象出2个概念,配置(config)和一批命令(batch)。由此对于这个封装的用法自然就可以想到:

1  config  =  SSHConfig.new(:host  =>   ' server.domain', :user => 'user', :password => 'pass')
2  batch  =  config.create_batch
3  batch  <<   ' ls'
4  batch  <<   ' ps -Al'
5  puts batch.run

有了这个蓝图,剩下的就是照着这个蓝图写代码了。首先SSHConfig就是用来保存服务器的配置,并且创建一个Batch对象。当然,通过前面看过net/ssh例子,可以想起来其实SSHConfig应该还有一个功能就是根据这些配置创建一个session

ExpandedBlockStart.gif 代码
 1  class  SSHConfig
 2    attr_accessor :user
 3    attr_accessor :host
 4    attr_accessor :password
 5    
 6    def initialize(args  =  {})
 7      @user  =  args[:user] unless args[:user].nil?
 8      @host  =  args[:host] unless args[:host].nil?
 9      @password  =  args[:password] unless args[:password].nil?
10     end
11    
12    def create_session
13      Net::SSH.start(host, user, :password  =>  password)  do  |ssh|
14        sess  =  Session.new(ssh)
15        yield sess
16       end
17     end
18    
19    def create_batch
20      Batch.new(self)
21     end
22  end

这里我还是把net/sshsession又包装了一下,只暴露出了一些自己用到的方法。下面就是Session类的代码:

ExpandedBlockStart.gif 代码
 1  class  Session
 2    def initialize(ssh)
 3      @ssh  =  ssh
 4      @stdout  =   ""
 5      @stderr  =   ""
 6     end
 7    
 8    def exec!(cmd)
 9      @ssh.exec!(cmd)  do  |ch, stream, data|
10         if  stream  ==  :stdout
11          stdout  <<  data
12        elsif stream  ==  :stderr
13          stderr  <<  data
14         end
15       end
16     end
17    
18    def stdout
19      @stdout
20     end
21    
22    def stderr
23      @stderr
24     end
25  end

Session对象截获了通过它执行的命令所造成的输出,供命令执行过后为脚本打印结果使用。

最后的重头戏是Batch,他用来保存一系列的命令,然后执行他们。

ExpandedBlockStart.gif 代码
 1  class  Batch
 2    def initialize(config,  & block)
 3      @config  =  config
 4      @commands  =  []
 5      @after_exec  =  block
 6     end
 7    
 8    def commands
 9      @commands
10     end
11    
12    def  << (item)
13      @commands  <<  item
14     end
15    
16    def add_command(cmd)
17      @commands  <<  cmd
18     end
19    
20    def run
21      ret  =   ""
22      @config.create_session  do  |sess|
23        @commands.each  do  |cmd|
24          sess.exec!(cmd)
25         end
26        unless @after_exec.nil?
27          @after_exec.call(sess)
28         end
29        ret  =  sess.stdout
30       end
31      ret
32     end
33  end

最后还有一个提示,就是通过SSH执行命令的话,两个不同的命令并不集成路径。也就是说如果先执行 cd ~\web, 然后执行 ls,那么ls返回的结果是 ~ 这个目录的,而不是~\web 。那么如何让cd这个命令起效果呢?用“; ” ── cd ~\web; ls

 


转载于:https://www.cnblogs.com/blacktear23/archive/2010/03/10/1682759.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值