Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

use ruby Net::SSH to read a remote file via sudo

Tags:

ssh

ruby

I have to read the contents of a remote file I have permissions to (sudo) read with cat,less or tail.

I am going to be doing this in Ruby so I assume I should be using Net::SSH to do it.

The file is a log file so it can be quite big.

This is the code I am trying now:

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

When I run that I get the following output:

in process in process in process data works in process in process in process in third "\r\n" remote end is done sending data shell terminated

The log actually currently has a few thousand lines of data in it, because I can read it from the actual server using putty.

How do I get that out from channel.on_data ?

Thanks

like image 708
user254694 Avatar asked Jun 11 '26 02:06

user254694


1 Answers

I think you need to add a \n to the password you send. This works for me. Note, The place where I commented out the else clause, you could possibly get the info from there too, but it works as you have it, but with a \n in the password.

require 'rubygems'
require 'net/ssh'

cmd = "sudo cat /var/log/mail.log"
HOSTNAME = "myhost.example.com"
USERNAME = "me"
PASSWORD = "12345"


Net::SSH.start( HOSTNAME , USERNAME, :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 #{USERNAME}:/
        puts "data works"
        channel.send_data "#{PASSWORD}\n"
      else
        #puts "OUTPUT NOT MATCHED: #{data}"
      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
like image 100
DGM Avatar answered Jun 13 '26 15:06

DGM



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!