mem
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
#!/bin/sh # 2008 Jon Mulder <mulderje@muohio.edu> AWK=/usr/bin/awk EGREP=/bin/egrep FREE=/usr/bin/free GREP=/bin/grep HEAD=/usr/bin/head PERL=/usr/bin/perl PS=/bin/ps SORT=/usr/bin/sort TOTALMEM=`$FREE -m | $GREP Mem | $PERL -pe 's/Mem:\s+([0-9]+).*/$1/'` RETVAL=0 case "$1" in nginx) $PS aux | $GREP nginx | $EGREP -v 'grep|/bin/sh' | $AWK -v totalmem="$TOTALMEM" 'BEGIN { total=0; printf "%-10s %-10s %-10s %s\n", "USER", "%MEM", "PID", "PROCESS TYPE" print "---------------------------------------------" } { printf "%-10s %-10.2f %-10s %s\n", $1, $4, $2, $12; total+=$4; } END { printf "%-10s %-10.2f %-0.0f MB used\n", "TOTAL:", total, (total/100)*totalmem }' RETVAL=$? ;; thin) $PS aux | $GREP thin | $EGREP -v 'grep|/bin/sh' | $AWK -v totalmem="$TOTALMEM" 'BEGIN { total=0; printf "%-10s %-10s %-10s %s\n", "USER", "%MEM", "PID", "SERVER:PORT" print "--------------------------------------------" } { printf "%-10s %-10.2f %-10s %s\n", $1, $4, $2, $13; total+=$4; } END { printf "%-10s %-10.2f %-0.0f MB used\n", "TOTAL:", total, (total/100)*totalmem }' RETVAL=$? ;; php) $PS aux | $GREP php5 | $EGREP -v 'grep|/bin/sh' | $AWK -v totalmem="$TOTALMEM" 'BEGIN { total=0; printf "%-10s %-10s %-10s %s\n", "USER", "%MEM", "PID", "EXECUTABLE" print "-------------------------------------------" } { printf "%-10s %-10.2f %-10s %s\n", $1, $4, $2, $11; total+=$4; } END { printf "%-10s %-10.2f %-0.0f MB used\n", "TOTAL:", total, (total/100)*totalmem }' RETVAL=$? ;; top) [ -n $2 ] && [ $2 -eq $2 2> /dev/null ] && NUM=$2 || ( NUM=10 && echo "$2 is not a number - Using 10 by default" ) $PS aux | $SORT -nr -k 4 | $HEAD -$NUM | $AWK -v totalmem="$TOTALMEM" 'BEGIN { total=0; printf "%-10s %-10s %-10s %-10s %s\n", "USER", "%MEM", "MEM", "PID", "EXECUTABLE" print "------------------------------------------------------" } { printf "%-10s %-10s %-10.2f %-10s %s\n", $1, $4, ($4/100)*totalmem, $2, $11; total+=$4; } END { printf "%-10s %-10.2f %-0.0f MB used\n", "TOTAL:", total, (total/100)*totalmem }' RETVAL=$? ;; *) echo "Usage: mem {nginx|thin|php|top [number]}" exit 1 ;; esac exit $RETVAL
Refactorings
No refactoring yet !
Marco Valtas
July 31, 2008, July 31, 2008 03:24, permalink
I think is a very good script, solves your problem and will be solely maintained by you. I have a handful of this kind of script in my ~/bin directory. But there's somethings I probably change. First is the reuse of you format string, you can make it less redundant just putting in a variable. Second, I don't fell comfortable mixing too much languages so, as a exercise, I tried to do this all in Perl. The problem was that I have a mac and could not paste the code here so you can use on your Linux without some tweaks here and there. If have some time you can look at the Perl module "Proc::ProcessTable" (http://is.gd/19PZ) which can provide a OO way to access this kind of information, this way you can expand your script more easily.
The third thing is that you can use VAR=`which perl` if you have all programs in your path and don't worry where they are in the system.
The thing is, your script is very good for some reasons I wrote before, I personally wouldn't bother to more flexible if not necessary. If you pick yourself adding more processes and for each one more redundancy then is time to fix.
Hope this helps.
JonM1827
July 31, 2008, July 31, 2008 04:32, permalink
Thanks a lot for the suggestions. I especially like the VAR=`which perl` idea. I never would have thought of that, yet it makes so much sense :)
I would have put the format string in a variable, but its a pain in the ass to pass variables to awk from the shell script; at least the way I was doing it... I hear what you are saying about the multiple languages, I just wanted to try out a few things that I had never really used.
And as far as the perl module goes, that looks really interesting!
Thanks for the help,
-Jon
So I use thin to serve my rails projects, php, and nginx as a back end for everything. I am on slicehost, and have a limited amount of memory to use. I know there are utilities like top and ps that are already out there, and I use them in this script, but I wanted to make something nice and easy for myself (mostly because I have never used a lot of these things)... I have never really made a shell script, used awk, parsed files with perl, etc. So bear that in mind while taking a look at this.
I was wondering what I could do to improve on this code, or if there was a better way to go about this in general. I actually looked a libproc, because I was going to do this in either c or c++, but I couldn't find any documentation on it.
To use the script you run it like: <name of script> {nginx|thin|php|top [number]}
If the first argument is either nginx, thin, or php it prints all of the information for those processes, and tells you how much memory each one of those processes are using, and gives it to you as a percentage based on how much RAM you have in your machine.
If you put in top as the first argument, you get the top ten memory using processes, also with the same information. But if you put in a number X as the second argument, then you get the top X memory using processes...
It's pretty self explanatory, but I thought I would give a brief description... Anyway let me know what you think.
Thanks,
Jon