2011-08-04 57 views
2

我試圖將輸入和處理分成兩部分,以便不必指定提示(如wait_for)。問題是該命令被接收,但從未處理。通道進程是從get_input線程調用的(它在on_process中打印puts),但什麼也沒有發生。紅寶石網/ ssh頻道死亡?

(該on_process僅在on_data被稱爲則信道只是坐在活躍後後調用一次?==真在這一點上仍然)

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 

回答

3

所以我想通了,在處理事件只是接收數據之後運行,並且SEND_DATA只是增加了數據隊列

所以要確保過程的事件多次運行... 添加此

session.loop(0.1)