Skip to content

Instantly share code, notes, and snippets.

@akm
Created December 8, 2019 11:39
Show Gist options
  • Save akm/76b117807305970e3e2d2048b5a67a5f to your computer and use it in GitHub Desktop.
Save akm/76b117807305970e3e2d2048b5a67a5f to your computer and use it in GitHub Desktop.

Revisions

  1. akm created this gist Dec 8, 2019.
    61 changes: 61 additions & 0 deletions ps_lsof.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,61 @@
    class Prcss
    attr_accessor :pid, :ppid, :command
    attr_reader :done

    def initialize(pid, ppid, command)
    @pid = pid.to_i
    @ppid = ppid.to_i
    @command = command
    end

    def children
    Prcss.list_by(pid.to_s).select{|p| p.ppid == pid }
    end

    def fd_count
    `lsof -p #{pid} | wc -l`.strip.to_i
    end

    def print
    return if done
    fd = fd_count
    puts '%d %d %d %s' % [pid, ppid, fd, command[0..150]] if fd > 0
    done = true
    end

    def print_as_tree
    return if done
    print
    children.each{|c| c.print_as_tree }
    end

    class << self
    def process_map
    @process_map ||= {}
    end

    def find_or_new(pid, ppid, command)
    process_map[pid.to_i] || Prcss.new(pid, ppid, command)
    end

    def list_by(str)
    cmd = "ps -e -o pid,ppid,command"
    cmd << "| grep '#{str}'" if str
    result = `#{cmd}`
    r = result.split("\n").map do |line|
    parts = line.split(/\s+/, 3)
    parts.length == 3 ? Prcss.find_or_new(*parts) : nil
    end
    r.reject{|p| p == nil || p.command =~ /\Agrep\s|\Aps \-e/}
    end

    end
    end

    if ARGV.length > 0
    ARGV.each do |arg|
    Prcss.list_by(arg).each(&:print_as_tree)
    end
    else
    Prcss.list_by(nil).each(&:print)
    end