1#!/usr/bin/perl 2# sort_res.perl5 - Script to group & sort lsof output by resource 3# 4# Copyright (c) 2004, 2005 - Fabian Frederick <fabian.frederick@gmx.fr> 5# 6# This program/include file is free software; you can redistribute it and/or 7# modify it under the terms of the GNU General Public License as published 8# by the Free Software Foundation; either version 2 of the License, or 9# (at your option) any later version. 10# 11# This program/include file is distributed in the hope that it will be 12# useful, but WITHOUT ANY WARRANTY; without even the implied warranty 13# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program (in the main directory of the Linux-NTFS 18# distribution in the file COPYING); if not, write to the Free Software 19# Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20# 21# Note : 22# -This script uses lsof released by Victor A. Abell 23# -lsof path recovery comes from standard perl scripts in there. 24# 25# Usage : 26# perl sort_res.perl5 -> display used resources + size 27# or perl sort_res.perl5 <program name> 28# 29# 12/2005 (FabF) 30# -size reset in loop (script was broken in 4.76) 31# -isexec looking in .. (like other scripts) 32# -display for one or all processes 33# -removing unuseful line number arg. 34# -display global size 35 36require 'getopts.pl'; 37my @args = @_; 38 39# Set path to lsof. 40if (($LSOF = &isexec("../lsof")) eq "") { # Some distros use lsof 41 # out of $PATH 42 if (($LSOF = &isexec("lsof")) eq "") { # Then try . and $PATH 43 if (($LSOF = &isexec("../lsof")) eq "") { # Then try .. 44 print "can't execute $LSOF\n"; exit 1 45 } 46 } 47} 48 49if ($ARGV[0] ne ""){ 50 $cmd="$LSOF -nPl -Fcns -c".$ARGV[0]."|"; 51}else{ 52 $cmd="$LSOF -nPl -Fcns|"; 53} 54 55#Parse lsof output to gather command, resource name, pid and size 56#Some extradata stand to keep script genericity 57$i=0; 58if (open(FILE, $cmd)){ 59 while (defined ($line=<FILE>)){ 60 $cline=$line; 61 $cline =~ s"^(.)""; 62 $cline =~ s/^\s+|\s+$//g; 63 if($line=~m/^p/){ 64 $pid=$cline; 65 }else{ 66 if($line=~/^s/){ 67 $size = $cline; 68 }else{ 69 if($line=~/^c/){ 70 $command = $cline; 71 }else{ 72 if($line=~/^n/){ 73 $name = $cline; 74 $data{$i} = { command => $command, name => $name, 75 pid => $pid , size => $size}; 76 $size=0; 77 $i = $i+1; 78 } 79 } 80 } 81 } 82 } 83} 84 85#Resource name sorting 86sub byresname { $data{$a}{name} cmp $data{$b}{name}} 87@ks=sort byresname (keys %data); 88 89#Resource grouping 90$i=0; 91$cname="a"; 92foreach $k (@ks){ 93 if ($data{$k}{name} ne $cname){ 94 $dgroup{$i} = { name => $data{$k}{name}, size => $data{$k}{size}}; 95 $cname = $data{$k}{name}; 96 $i++; 97 } 98} 99 100#Size sort on resource hash 101sub bysize { $dgroup{$a}{size} <=> $dgroup{$b}{size} } 102@ks=sort bysize (keys %dgroup); 103$gsize=0; 104printf(" -- KB -- -- Resource --\n", ); 105foreach $k (@ks){ 106 printf("%10d %s\n", $dgroup{$k}{size}/1024, $dgroup{$k}{name}); 107 $gsize+=$dgroup{$k}{size}; 108} 109 110printf("Total KB : %10d\n", $gsize/1024); 111## isexec($path) -- is $path executable 112# 113# $path = absolute or relative path to file to test for executabiity. 114# Paths that begin with neither '/' nor '.' that arent't found as 115# simple references are also tested with the path prefixes of the 116# PATH environment variable. 117 118sub 119isexec { 120 my ($path) = @_; 121 my ($i, @P, $PATH); 122 123 $path =~ s/^\s+|\s+$//g; 124 if ($path eq "") { return(""); } 125 if (($path =~ m#^[\/\.]#)) { 126 if (-x $path) { return($path); } 127 return(""); 128 } 129 $PATH = $ENV{PATH}; 130 @P = split(":", $PATH); 131 for ($i = 0; $i <= $#P; $i++) { 132 if (-x "$P[$i]/$path") { return("$P[$i]/$path"); } 133 } 134 return(""); 135} 136