0

我正在尝试使用 Net::SSH 连接到服务器,该服务器在登录后立即执行需要用户输入的脚本。用户必须输入“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    

任何想法,任何人?

提前致谢

4

5 回答 5

2

从远程服务器收到提示,您能否验证您的send_data呼叫是否正在发生?尝试在您的呼叫周围构建一个块,以便您可以在发送响应之前验证您是否从服务器获得了预期的提示。channel.on_datasend_data

您可能不想在exec这里使用。来自 Net::SSH::Connection::Channel 的文档:

发送一个通道请求,请求调用给定的命令。

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

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

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

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

如果您尝试(本质上)编写通常手动执行的 SSH 会话脚本,您可能会发现使用expect类似 - 的接口更容易(例如,像sshExpect这样的 gem可能值得一试)。

于 2010-02-08T17:18:28.433 回答
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    
于 2010-02-08T21:03:30.890 回答
0

我对 Net::SSH 库不是很熟悉,所以我对此本身无能为力,但听起来你可以使用Capistrano实现你想要的。

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

希望能帮助到你!

于 2010-02-08T16:56:29.397 回答
0

如果我"1\n"在 shell 中执行,我得到的回复是: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
于 2010-02-08T17:10:55.190 回答
0

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

于 2010-02-08T17:26:24.413 回答