在使用ruby和Net :: SSH进行第一次命令之前响应SSH提示

时间:2010-02-08 16:45:02

标签: ruby ssh net-ssh

我正在尝试使用Net :: SSH连接到紧接着之后的服务器 login执行需要用户输入的脚本。用户必须输入“1”或“2”,然后才能通过终端接收一些数据。

我的问题是,虽然我能够连接,但我找不到将“1 \ n”发送到服务器并接收输出的方法。

以下代码在“INFO - net.ssh.connection.session [80906b74]:channel_open_confirmation:0 0 0 32768”停止。

使用channel.exec(“1 \ n”)而不是channel.send_data也不会令人惊讶。

Net::SSH.start('host', 'user', :password => "pass", :auth_methods => ["password"], :verbose => :debug) do |session|

  session.open_channel do |channel|

    channel.on_data do |ch, data|
      STDOUT.print data
    end 

    channel.send_data( "1\n")

  end

  session.loop
end    

任何想法,任何人?

提前致谢

5 个答案:

答案 0 :(得分:2)

您是否可以在从远程服务器收到提示后验证您的send_data电话是否正在发生?尝试在channel.on_data调用周围构建send_data块,以便在发送响应之前验证是否从服务器获得了预期的提示。

您可能不想在此处使用exec。来自Net :: SSH :: Connection :: Channel:

的文档
  

发送要求的频道请求   调用给定的命令。

您希望发送文本字符串以回复提示,而不是调用命令。文档显示exec用于发送完整的CLI命令,如“ls -l / home”。

相反,send_data可能就是你想要的。文档显示它用于发送channel.send_data("the password\n")等任意文本。但是,请注意文档中的这句话:

  

请注意,它不会立即发送   整个频道的数据,但是   而只是附加给定的数据   到通道的输出缓冲区,   准备打包和   下次连接时发出   正在接受数据。

您可能需要查看channel.request_pty。它似乎是为与基于控制台的应用程序的交互而设计的。

如果您尝试(实质上)脚本通常手动执行的SSH会话,您可能会发现使用类似expect的界面更容易(例如,像{{3}这样的宝石可能值得一试。)

答案 1 :(得分:2)

谢谢大家指点。我已经能够解决问题 - 除了使用channel.request_pty之外,还需要请求shell。以下内容最终按预期工作:

Net::SSH.start('host', 'user', :password => "pass", :auth_methods => ["password"]) do |session|

  session.open_channel do |channel|

    channel.request_pty do |ch, success| 
      raise "Error requesting pty" unless success 

      ch.send_channel_request("shell") do |ch, success| 
        raise "Error opening shell" unless success  
      end  
    end

    channel.on_data do |ch, data|
      STDOUT.print data
    end 

    channel.on_extended_data do |ch, type, data|
      STDOUT.print "Error: #{data}\n"
    end

    channel.send_data( "1\n" )

    session.loop
  end  
end    

答案 2 :(得分:0)

我对Net :: SSH libs并不十分熟悉,所以我无法帮助解决这个问题,但听起来你可以用 Capistrano 实现你想要的目标。

例如,我有一个连接到远程服务器的capistrano任务,运行一个期望输入然后继续的命令。 Capistrano负责远程i / o。也许这可能是你的解决方案?

希望它有所帮助!

答案 3 :(得分:0)

如果我在shell中执行"1\n",我得到的回复是:bash: 1: command not found

如果我执行echo "1",我会:1

您确定要尝试执行要发送的文字吗?也许你正在寻找类似的东西:

output = ""
Net::SSH.start('host', 'user', :password => "pass") do |ssh|
   output = ssh.exec! "echo 1"
end
puts output

答案 4 :(得分:0)

我不熟悉那个lib,但是在SSH上你可以打开多个频道。也许服务器只响应第一个默认通道,如果你打开另一个默认通道,你就会得到一个新的shell。