使用ruby Net :: SSH通过sudo读取远程文件
我必须读取一个远程文件的内容,我有权使用cat,less或tail读取(sudo)。
我将在Ruby中执行此操作,因此我假设我应该使用Net :: SSH来执行此操作。
该文件是一个日志文件,因此它可能非常大。
这是我现在正在尝试的代码:
require 'rubygems' require 'net/ssh' cmd = "sudo cat /var/logs/httpd/ACCESS_log.2012.03.23" Net::SSH.start( "SERVER" , "USER", :password => "PASSWORD") do |ssh| ssh.open_channel do |channel| channel.request_pty channel.exec(cmd); channel.on_close do puts "shell terminated" end channel.on_eof do |ch| puts "remote end is done sending data" end channel.on_extended_data do |ch, type, data| puts "got stderr: #{data.inspect}" end channel.on_data do |channel, data| if data =~ /^\[sudo\] password for USER:/ puts "data works" channel.send_data 'PASSWORD' end channel.on_data do |ch,data| puts "in third" puts data.inspect end end channel.on_process do |ch| puts "in process" end ssh.loop end end
当我运行时,我得到以下输出:
在过程中的过程中数据工作过程中的过程中第三个“\ r \ n”远程端完成发送数据shell终止
该日志实际上当前有几千行数据,因为我可以使用putty从实际服务器读取它。
我如何从channel.on_data中解决这个问题?
谢谢
我认为您需要在发送的密码中添加\n
。 这对我有用。 注意,在我注释掉else子句的地方,你也可以从那里获取信息,但它可以正常工作,但密码中有\n
。
需要'rubygems' 要求'net / ssh' cmd =“sudo cat /var/log/mail.log” HOSTNAME =“myhost.example.com” USERNAME =“我” 密码=“12345” Net :: SSH.start(HOSTNAME,USERNAME,:password => PASSWORD)执行| ssh | ssh.open_channel do | channel | channel.request_pty channel.exec(CMD); channel.on_close做 把“shell终止” 结束 channel.on_eof do | ch | 把“远程端完成发送数据” 结束 channel.on_extended_data do | ch,type,data | 把“得到stderr:#{data.inspect}” 结束 channel.on_data do | channel,data | 如果#{USERNAME}的数据=〜/ ^ \ [sudo \]密码:/ 把“数据工作” channel.send_data“#{PASSWORD} \ n” 其他 #puts“OUTPUT NOT MATCHED:#{data}” 结束 channel.on_data do | ch,data | 把“放在第三” 把data.inspect 结束 结束 channel.on_process do | ch | 把“进行中” 结束 ssh.loop 结束 结束
您正在执行on_data
回调时替换新的on_data
回调。 我没有说服Net :: SSH的内部,但这可能会产生令人惊讶的行为。
尝试将两个on_data回调中的代码更改为一个,看看是否有帮助。
channel.on_data do |channel, data| if data =~ /^\[sudo\] password for USER:/ puts "data works" channel.send_data 'PASSWORD' else puts "in third" puts data.inspect if end
作为旁注,由于您需要sudo来阅读日志,因此有人认为他们和该服务器值得保护。 看起来你正在嵌入密码,这些密码可以在这个ruby程序中提供对服务器的特权访问。 这意味着任何能够阅读该程序的人都可以获得相同的特权访问权限。 您将如何限制在此程序中访问密码?
require 'net/ssh' Net::SSH.start('host', 'user', :password => "password") do |ssh| # capture all stderr and stdout output from a remote process output = ssh.exec!("hostname") puts output # capture only stdout matching a particular pattern stdout = "" ssh.exec!("ls -l /home/jamis") do |channel, stream, data| stdout << data if stream == :stdout end puts stdout # run multiple processes in parallel to completion ssh.exec "sed ..." ssh.exec "awk ..." ssh.exec "rm -rf ..." ssh.loop # open a new channel and configure a minimal set of callbacks, then run # the event loop until the channel finishes (closes) channel = ssh.open_channel do |ch| ch.exec "/usr/local/bin/ruby /path/to/file.rb" do |ch, success| raise "could not execute command" unless success # "on_data" is called when the process writes something to stdout ch.on_data do |c, data| $stdout.print data end # "on_extended_data" is called when the process writes something to stderr ch.on_extended_data do |c, type, data| $stderr.print data end ch.on_close { puts "done!" } end end channel.wait # forward connections on local port 1234 to port 80 of www.capify.org ssh.forward.local(1234, "www.capify.org", 80) ssh.loop { true } end
最新文件17.11.25