vkill'blog

“技术本身没有太多价值,掌握了新的思考方式才是真的收获”

net/ssh 或 open3 中执行 'passwd user' 命令时的问题

18:19 , vkill
前几天用 open3 的时候,做个执行 'passwd user' 命令的实验,因为这个要输入两次密码,既要执行两次 stdin ,后面看输出的时候,发现 stdout 为 nil ,而 stderr 才是我们看到的输出,当时也就没在意

昨天用 net/ssh 的时候,又拿执行 'passwd user' 命令实验

这个是官方的一个例子
Quotation

    #   Net::SSH.start("host", "user") do |ssh|
    #     ssh.exec! "cp /some/file /another/location"
    #     hostname = ssh.exec!("hostname")
    #
    #     ssh.open_channel do |ch|
    #       ch.exec "sudo -p 'sudo password: ' ls" do |ch, success|
    #         abort "could not execute sudo ls" unless success
    #
    #         ch.on_data do |ch, data|
    #           print data
    #           if data =~ /sudo password: /
    #             ch.send_data("password\n")
    #           end
    #         end
    #       end
    #     end
    #
    #     ssh.loop
    #   end


我就照着这个例子改了下,把 "sudo -p 'sudo password: ' ls" 改为了 "passwd user" ,也把 if data=~// 那行的正则改了下,执行发现脚本进入了死循环,不得其解
后来就又去把 /lib/net/ssh/connection/channel.rb 看了看,看了下里面的 on_data、on_extended_data、send_data、on_request 这四个method,在结合前些天使用 open3 里的经验,修改后的脚本如下

require 'rubygems'
require 'net/ssh'
Net::SSH.start("192.168.9.109", "root",:password=>'1234567') do |ssh|
  #ssh.exec! "cp /some/file /another/location"
  #hostname = ssh.exec!("hostname")
  ssh.open_channel do |ch|
    ch.exec "passwd aaa" do |ch, success|
      abort "could not execute passwd aaa" unless success
      ch.on_extended_data do |ch, type, data|
        puts data
        if data =~ /password: /
          ch.send_data("123\n")
        end
      end
    end
  end
  ssh.loop
end

现在再执行一切正常,这里就是把 on_data 改为了 on_extended_data

好了,现在就找到答案了
'sudo ls /' 这样的命令输出是在 stdout,而 'passwd user' 这样的命令输出是在 stderr
所以我们不管是使用 open3,还是使用 net/ssh ,都要先确定一下输入的时候到底是在 stdout 还是 stderr 中

Last modified by vkill on2010/06/21 19:11
类别:ruby & rails | Tags: , , , , , , | 0 条评论, 1012 次阅读
网友评论(0):
发表评论:

Nickname: 
Email:
Site URI: