rendered paste body#!/usr/bin/perl
use strict;
use warnings;
my $filter = "-e";
my $list = `ps -o pid,cmd $filter --no-headers`;
$list =~ s/^\n$/$1/m;
my @processes = (map { /(\d+)\s+(.+)/; {pid => $1, cmd => $2} } split("\n", $list));
for my $proc (@processes) {
$proc->{swapped} = 0;#print "/proc/$proc->{pid}/smaps\n";
$proc->{resident} = 0;
$proc->{total} = 0;
next if !-e "/proc/$proc->{pid}/smaps";
open SMAPS, "</proc/$proc->{pid}/smaps";
while(<SMAPS>) {
$proc->{swapped} += int($1) if(/Swap:\s+(\d+)/);
}
close SMAPS;
next if !-e "/proc/$proc->{pid}/statm";
open STATM, "</proc/$proc->{pid}/statm";
($_ = <STATM>) =~ /^\d+ (\d+)/;
$proc->{resident} = $1 * 4; # statm is in pages, pages are currently 4k (figure out how to actually get page size)
$proc->{total} = $proc->{swapped} + $proc->{resident};
}
@processes = sort{ $::a->{total} <=> $::b->{total} } @processes;
if ($ARGV[0]) {
shift @processes while @processes > $ARGV[0];
}
my %longest = (pid => 3, total_str => 5, resident_str => 8, swapped_str => 7);
my @units = ('k', 'M', 'G');
for my $p (@processes) {
for (('total', 'resident', 'swapped')) {
$p->{"${_}_unit"} = 0;
my $siz = $p->{$_};
while ($siz >= 1024 && $p->{"${_}_unit"} < @units) {
$p->{"${_}_unit"} += 1;
$siz /= 1024.0;
}
$p->{"${_}_str"} = sprintf("%.2f %sB", $siz, $units[$p->{"${_}_unit"}]);
}
for (keys %longest) {
$longest{$_} = length $p->{$_} if (length $p->{$_} > $longest{$_});
}
}
print "TOTAL". (" "x ($longest{total_str}-5)) .
" (RESIDENT". (" "x ($longest{resident_str}-8)) ." + SWAPPED". (" "x ($longest{swapped_str}-7)) .") ".
"PID". (" "x ($longest{pid}-3)) ." NAME\n";
print "----------------\n";
my $i = 0;
for(@processes) {
my %padding = ();
foreach my $l (keys %longest) {
$padding{$l} = " " x ($longest{$l} - length $_->{$l});
}
print "$_->{total_str}$padding{total_str} ".
"($_->{resident_str}$padding{resident_str} + $_->{swapped_str}$padding{swapped_str}) ".
"$_->{pid}$padding{pid} $_->{cmd}\n" if $_->{resident} > 0;
if (++$i == 40) {
$i = 0;
print "----------------\n";
print "TOTAL". (" "x ($longest{total_str}-5)) .
" (RESIDENT". (" "x ($longest{resident_str}-8)) ." + SWAPPED". (" "x ($longest{swapped_str}-7)) .") ".
"PID". (" "x ($longest{pid}-3)) ." NAME\n";
print "----------------\n";
}
}
print "----------------\n" if $i;
my ($total, $unit);
$total = 0;
$total += $_->{resident} for(@processes);
for ($unit = 0; $unit < 2 && $total > 1024; $unit++) {
$total /= 1024;
}
printf "Total Resident: %.2f $units[$unit]B\n", $total;
$total = 0;
$total += $_->{swapped} for(@processes);
for ($unit = 0; $unit < 2 && $total > 1024; $unit++) {
$total /= 1024;
}
printf "Total Swapped: %.2f $units[$unit]B\n", $total;
$total = 0;
$total += $_->{total} for(@processes);
for ($unit = 0; $unit < 2 && $total > 1024; $unit++) {
$total /= 1024;
}
printf "Total: %.2f $units[$unit]B\n", $total;