2010-02-08 65 views
0

我试图使用Net :: SSH连接到服务器,该服务器在 登录后立即执行需要用户输入的脚本。用户必须输入“1”或“2”,之后将通过终端接收一些数据。在使用ruby和Net :: SSH的第一个命令之前响应SSH提示

我的问题是,虽然我能够连接,但我找不到一种方法向服务器发送“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  

任何想法,任何人?

在此先感谢

回答

2

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

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

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

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

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

注意,它不会立即发送 数据横渡英吉利海峡,但 不是仅仅附加给定的数据 到通道的输出缓冲器, 筹备被打包并且 在下次连接 正在接受数据时发出。

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

如果你想(本质)脚本,你通常会做手工,你可能会发现它更容易使用的expect式的接口的SSH会话(例如,像sshExpect宝石可能是值得一试) 。

+0

我实际上已经尝试过使用channel.request_pty,请求成功,但数据既没有被发送也没有被接收(使​​用channel.send_data) – Molotoff 2010-02-08 17:45:17

+0

如何验证我是否从远程服务器获得提示? – Molotoff 2010-02-08 17:48:53

+0

在您的'channel.on_data do | ch,data | ...结束“块,变量”data“将保存从服务器发送给您的数据。在该块内部,将它放到控制台/日志文件中,并以可视方式进行检查。一旦你看到了服务器的提示符的格式,你可以编写代码来解析它。你可能会尝试像'puts'这样的数据:#{data.inspect}“'。 – bta 2010-02-09 16:54:48

0

我并不十分熟悉的Net :: SSH库,所以我不能与每本身帮助,但它听起来就像你可以达到你想要使用Capistrano的什么。

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

希望它有帮助!

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 
+0

问题是,我想发送“1 \ n”到等待另一端的脚本的STDIN。 – Molotoff 2010-02-08 17:29:00

+0

是否有任何理由不只是打开一个套接字并在远程机器上侦听? – ezpz 2010-02-08 21:03:11

0

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

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