Ulrich Spoerlein
2007-May-03 08:11 UTC
[Net-ssh-users] How to get buffered line output via SSH
Hi,
I''m using ruby to process maillogs into RRD and want to have it work
in near realtime. All the processing code is already working fine,
what I''m missing is a way to attach to a remote file via SSH and get
the output line by line.
For that, I''m using tail(1), the problem with Net::SSH is, that I
don''t know how I can have my code call a process_line() function *per*
line. It absolutely must be called with a complete line of the maillog
output.
Right now I''m using the following hack, but something more elegant
would be nice. Any ideas? (My ruby is not very good)
# Either attach tail(1) to a remote file through SSH, or read from
# stdin or files on command line
if $rhost and $rfile
require ''net/ssh''
# Start an SSH session, and set up a control channel
Net::SSH::Session.new("$rhost", ''root'') do
|session|
session.open_channel do |channel|
# Install callbacks for various events
# NB: on_data will not return complete lines, and we can''t pass
# partial lines to process_line(), therefore, buffer the output
# with a crude hack.
buffer = ''''
channel.on_data do |ch, data|
data.each_line do |line|
if line =~ /\n$/
process_line(buffer+line)
buffer = ''''
else
buffer = line
end
end
end
# execute tail on the remote file. It will start at line 0 and
# never terminate (someone else has to whack this ruby script, to
# terminate it.
channel.exec "tail -n +0 -f #$rfile"
end
session.loop
end
else
# Read from stdin or from the command line.
while line = gets
process_line(line)
end
end
Cheers,
Uli