All pastes #1903818 Raw Edit

Something

public text v1 · immutable
#1903818 ·published 2010-07-19 17:48 UTC
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;