harry’s memorandum

おれおれメモ

ruby で pstree

rubyで書く簡易版pstreeはこんな感じかな。

class PsTree
  def initialize
    @line = "-"
    @space = " "
    @table = Hash.new{|h,k| h[k] = []}
    proc_dat
  end
  def proc_dat
    Dir.glob("/proc/[0-9]*") {|dir|
      stat = stat_open("#{dir}/stat")
      pid = stat[0]; ppid = stat[1]; comm = stat[2]
      cmdline = cmdline_open("#{dir}/cmdline")
      cmdline = "[#{comm}]" if cmdline.size == 0
      @table[ppid] << {pid => cmdline}
    }
    @table
  end
  def stat_open(stat)
    st = open(stat).read.split
    [st[0], st[3], st[1][1,st[1].size-2]]
  end
  def cmdline_open(cmdline)
    open(cmdline).read.gsub(/\000/,@space).strip
  end
  def tree(c=0,pid=0)
      exit if @table[pid.to_s].nil?
      c += 1
      @table[pid.to_s].each {|h|
        h.each_pair{|k,v|
          line = @line*c + ">"
          puts "#{line} #{k}: #{v}"
          tree(c,k)
        }
      }
  end
end

pt = PsTree.new
pt.tree

結果はこんな感じ。

$ ruby pstree.rb
--> 2082: /usr/sbin/sshd
---> 9304: sshd: foo [priv]
----> 9306: sshd: foo@pts/2
-----> 9307: -bash
------> 9380: screen
-------> 9381: SCREEN
--------> 9382: -/bin/bash
---------> 9618: ruby pstree.rb
--------> 9410: -/bin/bash
--------> 9438: -/bin/bash
--------> 9466: -/bin/bash