使用ruby和Net::SSH在第一个命令之前响应SSH提示
我正在尝试使用Net::SSH连接到一个服务器,该服务器在 login执行需要用户输入的脚本。用户必须输入“1”或“2”,然后将通过终端接收一些数据 我的问题是,尽管我能够连接,但我无法找到将“1\n”发送到服务器并接收输出的方法 下面的代码停在“INFO--net.ssh.connection.session[80906b74]:channel_open_confirmation:032768” 使用channel.exec(“1\n”)而不是channel.send\u数据也不足为奇地不起作用使用ruby和Net::SSH在第一个命令之前响应SSH提示,ruby,ssh,net-ssh,Ruby,Ssh,Net Ssh,我正在尝试使用Net::SSH连接到一个服务器,该服务器在 login执行需要用户输入的脚本。用户必须输入“1”或“2”,然后将通过终端接收一些数据 我的问题是,尽管我能够连接,但我无法找到将“1\n”发送到服务器并接收输出的方法 下面的代码停在“INFO--net.ssh.connection.session[80906b74]:channel_open_confirmation:032768” 使用channel.exec(“1\n”)而不是channel.send\u数据也不足为奇地不起作
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
有什么想法吗
提前感谢我对Net::SSH libs不太熟悉,因此我无法帮助您实现这一点,但听起来您可以使用Capistrano实现您想要的功能 例如,我有一个capistrano任务,它连接到远程服务器,运行一个命令,该命令需要输入,然后继续。Capistrano负责远程i/o。也许这对你来说是个解决办法
希望有帮助 我对Net::SSH libs不太熟悉,因此我无法帮助您实现这一点,但听起来您可以使用Capistrano实现您想要的功能 例如,我有一个capistrano任务,它连接到远程服务器,运行一个命令,该命令需要输入,然后继续。Capistrano负责远程i/o。也许这对你来说是个解决办法 希望有帮助 如果我在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
如果我在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
在收到远程服务器的提示后,您是否可以验证您的
send\u data
调用是否正在进行?尝试构建一个频道。在发送\u数据
调用周围的\u数据
块上,这样您就可以在发送响应之前验证是否从服务器收到了预期的提示
您可能不想在此处使用exec
。从Net::SSH::Connection::Channel的文档:
发送一个通道请求,请求
可以调用给定的命令
您希望发送文本字符串以答复提示,而不是调用命令。文档显示exec
用于发送完整的CLI命令,如“ls-l/home”
相反,send_data
可能是您想要的。文档显示它用于发送任意文本,如频道。发送数据(“密码”)
。但是,请注意,文件中的这句话:
请注意,它不会立即发送
数据通过通道传输,但是
而只是附加给定的数据
到通道的输出缓冲区,
准备打包和
下一次连接时发送
正在接受数据
你可能想看看。它似乎是为与基于控制台的应用程序交互而设计的
如果您试图(本质上)编写通常手动执行的SSH会话脚本,您可能会发现使用类似
expect
的接口更容易(例如,类似gem的接口可能值得一试)。您能否验证在收到远程服务器的提示后是否正在调用send\u data
?尝试构建一个频道。在发送\u数据
调用周围的\u数据
块上,这样您就可以在发送响应之前验证是否从服务器收到了预期的提示
您可能不想在此处使用exec
。从Net::SSH::Connection::Channel的文档:
发送一个通道请求,请求
可以调用给定的命令
您希望发送文本字符串以答复提示,而不是调用命令。文档显示exec
用于发送完整的CLI命令,如“ls-l/home”
相反,send_data
可能是您想要的。文档显示它用于发送任意文本,如频道。发送数据(“密码”)
。但是,请注意,文件中的这句话:
请注意,它不会立即发送
数据通过通道传输,但是
而只是附加给定的数据
到通道的输出缓冲区,
准备打包和
下一次连接时发送
正在接受数据
你可能想看看。它似乎是为与基于控制台的应用程序交互而设计的
如果您试图(本质上)编写通常手动执行的SSH会话脚本,您可能会发现使用类似
expect
的接口更容易(例如,类似gem的接口可能值得一试)。我不熟悉该库,但在SSH上您可以打开多个通道。可能服务器只响应第一个默认通道,如果打开另一个通道,您将获得一个新的shell。我不熟悉该库,但在SSH上,您可以打开多个通道。可能服务器只响应第一个默认通道,如果打开另一个通道,则会得到一个新的shell。谢谢大家的指点。我已经能够指出这个问题——除了使用channel.request,还需要请求一个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
谢谢大家的指点。我已经能够指出这个问题——除了使用channel.request,还需要请求一个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
问题是,我想将“1\n”发送到另一端等待的脚本的STDIN。是否有任何原因使您不只是op