Asp Forum
Home
|
Login
|
Register
|
Search
Forums
>
comp.lang.ruby
How to optimize my ruby code
Valentino Lun
11/11/2008 12:37:00 PM
I am writing a script to get the process image in unix through ssh, then
insert the record to database. As I am a new ruby user, I think my
method is quite stupid and I would like to know if you can make my code
prettier. Thanks.
Below is the ps image in my unix server (command : ps auxww)
USER PID %CPU %MEM SZ RSS TTY STAT STIME TIME COMMAND
\n
testrrs1 2429158 0.0 0.0 15588 15624 - A 13:27:12 0:00 java
lis.rpt.PostPrtMain /appl/lis/home2/testrrs1/config/PPRT_3.att \n
testlib 2425018 0.0 0.0 3052 4772 - A May 29 0:00
/appl/lis/home/lib/test/work/rls_server -i/appl/lis/home/lib/test/w \n
====start of script===
require "rubygems"
$LOADED_FEATURES[$LOADED_FEATURES.length] =
'net/ssh/authentication/pageant.rb'
require 'net/ssh'
require "active_record"
$config = YAML.load_file(File.join(File.dirname(__FILE__),
'database.yml'))
ssh=Net::SSH.start("hostname", "account", :port => 12345, :paranoid =>
false, :auth_methods => ["publickey"], :passphrase => "testing", :keys
=> ["C:/testing/id_rsa"])
ps=ssh.exec!("ps auxww | head -30")
ssh.close
ps=ps.to_a
for idx in (0...ps.length)
next if idx==0 #skip the header
ps_user=ps[idx].split[0]
ps_pid=ps[idx].split[1]
ps_cpu=ps[idx].split[2]
ps_mem=ps[idx].split[3]
ps_sz=ps[idx].split[4]
ps_rss=ps[idx].split[5]
ps_tty=ps[idx].split[6]
ps_stat=ps[idx].split[7]
# The STIME field may equal to May 29 or 13:27:12, and the COMMAND
has unknown number of space.
if (ps[idx].split[8].include?(":"))
ps_stime=ps[idx].split[8]
ps_cmd=ps[idx].split[9]+" "+ps[idx].split[10]+" "+ ... +
ps[idx].split[ps[idx].length]
else
ps_stime=ps[idx].split[8]+" "+ps[idx].split[9]
ps_cmd=ps[idx].split[10]+" "+ps[idx].split[11]+" "+ ... +
ps[idx].split[ps[idx].length]
end
MyTable.create(:ps_user => ps_user, :ps_pid => ps_pid, ...SKIP...
:ps_cmd => ps_cmd)
end
====end of script===
Thank you very much for your kind assistance.
--
Posted via
http://www.ruby-...
.
2 Answers
Brian Candler
11/11/2008 12:56:00 PM
0
Valentino Lun wrote:
> ps=ps.to_a
> for idx in (0...ps.length)
This is fine since you use idx later on to skip the first line, although
an alternative is
ps.to_a.each_with_index do |line, idx|
> next if idx==0 #skip the header
> ps_user=ps[idx].split[0]
> ps_pid=ps[idx].split[1]
> ps_cpu=ps[idx].split[2]
> ps_mem=ps[idx].split[3]
> ps_sz=ps[idx].split[4]
> ps_rss=ps[idx].split[5]
> ps_tty=ps[idx].split[6]
> ps_stat=ps[idx].split[7]
user, pid, cpu, mem, sz, rss, tty, stat, *rest = line.split
> # The STIME field may equal to May 29 or 13:27:12, and the COMMAND
> has unknown number of space.
> if (ps[idx].split[8].include?(":"))
> ps_stime=ps[idx].split[8]
> ps_cmd=ps[idx].split[9]+" "+ps[idx].split[10]+" "+ ... +
> ps[idx].split[ps[idx].length]
> else
> ps_stime=ps[idx].split[8]+" "+ps[idx].split[9]
> ps_cmd=ps[idx].split[10]+" "+ps[idx].split[11]+" "+ ... +
> ps[idx].split[ps[idx].length]
> end
if rest[0].include?(":")
stime, cmd = rest[0], rest[1..-1].join(" ")
else
stime, cmd = rest[0]+" "+rest[1], rest[2..-1].join(" ")
end
But a shorter (and still very efficient) way is to write a big Regexp
for matching all this:
PS_LINE = %r{^
(\S+) \s+ # user
(\S+) \s+ # pid
(\S+) \s+ # cpu
(\S+) \s+ # mem
(\S+) \s+ # sz
(\S+) \s+ # rss
(\S+) \s+ # tty
(\S+) \s+ # stat
(\d\d:\d\d:\d\d | \w\w\w\s\d\d) \s+ # stime
(.*) # cmd
$}x
ps.each_line do |line|
if PS_LINE =~ line
MyTable.create(:ps_user => $1, :ps_pid => $2, ...SKIP...
:ps_cmd => $10)
end
end
The 'x' flag to a Regexp lets you embed spaces and comments to make it
more readable. You can tweak it to match the data more precisely, e.g.
use (\d+) instead of (\S+) to match the pid, so that any unexpected
lines are ignored.
--
Posted via
http://www.ruby-...
.
Valentino Lun
11/11/2008 1:31:00 PM
0
Thank you for your clear explanation. I think I learned a great lesson.
--
Posted via
http://www.ruby-...
.
Servizio di avviso nuovi messaggi
Ricevi direttamente nella tua mail i nuovi messaggi per
How to optimize my ruby code
Inserendo la tua e-mail nella casella sotto, riceverai un avviso tramite posta elettronica ogni volta che il motore di ricerca troverà un nuovo messaggio per te
Il servizio è completamente GRATUITO!
x
Login to ForumsZone
Login with Google
Login with E-Mail & Password