开发者

ruby net/ssh channel dies?

Im trying to break the input and the processing into two parts so that the prompts don't have to be specified (like wait_for). the problem is that the command is received however never processed. the channel process is called from the get_input thread (it prints the puts in the on_process) but nothing ever happens.开发者_开发知识库

(the on_process is only called once after after the on_data is called then the channel just sits active? == true at this point still)

ENV['PATH'] = 'H:\mydocu~1\usrbin\ansi140\x86;' + ENV['PATH']
`ansicon.exe -p`

require 'net/ssh'

hostname = "server"
username = "user"
password = "password"

@data = ''
@print = true
@cmd = ''

#clear the log
File.open('ssh_command.log', 'w') {|f| f.write('')}


get_input = Thread.new { 
      while true
        @cmd = nonblocking_stdin_gets
        exit if @cmd.strip == "Q"
        File.open('ssh_command.log', 'a+') { |f| f.write("{#{@cmd}}") } 
        if @cmd.rstrip != '' or @cmd =~ /\r?\n/
          puts "sending..."
          @print = false
          @openchannel.process
        end
      end 
    }

if RUBY_PLATFORM =~ /win32/
  require 'Win32API'
  $win32_console_kbhit = Win32API.new("msvcrt", "_kbhit", [], 'I')
  def console_input_ready?
    $win32_console_kbhit.call != 0
  end
  def nonblocking_stdin_gets
    sleep(0.1) until console_input_ready?
    $stdin.gets # don't bother to use getc, it also blocks until user hits <return>
  end
else
  def nonblocking_stdin_gets
    $stdin.gets # it just works, on unix
  end
end

@openchannel = nil

Net::SSH.start(hostname, username, :password => password) do |session|

  @openchannel = session.open_channel do |channel|

    channel.on_data do |ch, data|
      @data += data
    end 

    channel.on_extended_data do |ch, type, data|
      puts "got stderr: #{data}"
    end

    channel.on_request "exit-status" do |ch, data|
      puts "process terminated with exit status: #{data.read_long}"
    end

    channel.on_open_failed { |ch, code, desc| puts "err: #{desc}" }

    # must come before shell
    channel.request_pty :term => "xterm" do |ch, success|
      if success
        puts "pty successfully obtained"
      else
        puts "could not obtain pty"
      end
    end

    channel.send_channel_request "shell" do |ch, success|
      if success
        puts "user shell started successfully"
      else
        puts "could not start user shell"
      end
    end

    channel.on_eof do |ch|
      puts "remote end is done sending data"
    end

    channel.on_close do |ch|
      puts "channel is closing!"
    end

    channel.on_process do |ch|
      print @data if @print
      puts "command:#{@cmd}"
      if @cmd.rstrip != '' or @cmd =~ /\r?\n/
        #system("cls")
        channel.send_data(@cmd.rstrip + "\r\n")
        @cmd = ''
        @print = true
      else
        puts "no command"
      end 
    end

  end #channel_end
  session.loop 
end #session_end


so I figured it out, the processing event is only run after data is received, and the send_data only adds to the data queue

so to make sure that the process event is run multiple times... add this

session.loop(0.1)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜