List TOP n memory-consuming processes in Linux


Please note that this blog has been moved.

Now it has its own domain: mynixworld.info🙂

If you want to read the latest version of this article (recommended) please click here and I open the page for you.

From time to time I need to check my systems memory usage and what processes is consuming the most of it. Sure, there is a ps command or a top command which can handle well this kind of job, but what a heck, we want to practice little bit bash commands, right?

#!/bin/bash

###################################################################################################
#
#                   Simple script for getting TOP n memory-consumming processes
#
#  NOTE: The information shown on output comes from ps-command so is somehow kernel-dependent.
#
#  Options:
#      -u <list> : a comma-delimited list of users for which we query the memory usage
#      -c        : clear the cache(garbage) memory before querying memory usage
#      -t <n>    : specify how to trim the output; when n=0 or not specified then the script will attempt to
#                  determine the terminal's visible lines and to adapt n to that
#      -p <pid>  : filter output to specific pid; when pid not specified then will filter the output by current process pid
#      -f        : display command parameter list, otherwise display just the command full path
#      -h        : display help ussage
#
#     Comment    : This code is far from beeing elegant/bullet-proof but it's doing its job reasonably ;o)
#
#     Usage example: topfree -u root,myusername -t 30 -c
#
#                    The above command will: (1) drop the cache memory and (2) output the most 30 
#                    memory-consuming processes for user "root" and "myusername"
#
#                    topfree -u "" -t 0 (or just run ./free.sh without parameters)
#
#                    The above command will (1) determine the number "n" of visible lines of your
#                    terminal and (2) will output the most "n" memory-consuming processes for
#                    any user (see the empty user list "")
#
#     Author : eugenmihailescux at gmail dot com
#     Last update : 02.Oct.2011
#
##################################################################################################

# variable initialization
MB=1024 # memory information will be expresed in MB insted of mb

# read the command-line parameter
while getopts ":cfhp:t:u:" optname
  do
    case "$optname" in
      "c")
        cc="1"
        ;;
      "t")
        top=$OPTARG
        ;;
      "u")
        p_user=$OPTARG
        ;;
      "f")
        f_list="1"
        ;;
      "p")
	ppid="1"
        pid=$OPTARG
	if [ -n "$pid" ];then
		pid="-p $pid"
	fi
        ;;
	":")
	if [ $OPTARG="p" ];then
		ppid="1"
	fi
          ;;
      "h")
	echo
	echo "Simple script for getting TOP n memory-consumming processes (v0.1)"
        echo " usage   : $0 [options]"
        echo " options :"
        echo -e "\t-u <list> : a comma-delimited list of users for which we query the memory usage"
        echo -e "\t-c        : clear the cache(garbage) memory before querying memory usage"
        echo -e "\t-t <n>    : specify how to trim the output; when n=0 or not specified then the script will attempt to determine the terminal's visible lines and to adapt n to that"
	echo -e "\t-p <pid>  : filter output to specific pid; when pid not specified then will filter the output by current process pid"
	echo -e "\t-f        : display command parameter list, otherwise display just the command full path"
        echo -e "\t-h        : display help ussage"
        exit 0
        ;;
    esac
  done

let "mem=`cat /proc/meminfo |head -1|awk '{print $2}'`/1000" # meminfo is shown in kB not KB

if [ -n "$ppid" ]; then
	user=$pid
	user_str="current command"
else
	if [ -z "$p_user" ];then
		user="ax"
		user_str="any user"
	else
		user="aU "$p_user
		user_str="user [$p_user]"
	fi
fi

if [ -z "$top" ];then
	let "top=$(tput lines)-9" # adjust terminal rows number
else
	if [ "$top" == 0 ];then
		let "top=$(tput lines)-9" # adjust terminal rows number
	fi
fi

if [ -n "$cc" ]; then
	if [ "$(whoami)" != "root" ]; then
		echo "[!] : Cache dropping require 'su' password"
		su -c "sync && echo 3 > /proc/sys/vm/drop_caches"
		err=$?
		ccdone=0
	else
		ccdone=-1
	fi

	if [ $ccdone -lt 0 ]; then
		su -c "sync && echo 3 > /proc/sys/vm/drop_caches"
		err=$?
	fi

        if [ $err -eq 0 ]; then
		echo " INFO : Cache dropped successfuly!"
                let "top=$top-5" # adjust terminal rows number
	else
		echo " WARNING : Cache not dropped due to an unexpected error" 
	fi
fi

echo ""
echo -e "  \033[1;33mThe TOP $top memory-consuming processes of $user_str are:\033[0m"
echo "================================================================"
echo -e "\033[7m PID    User     (%)    Size(MB)       Process name             \033[0m"
echo "================================================================"
sep="@!@"
ps hu $user| awk '{cmd_param=""; for (i=12;i<=NF && f_list=="1";i++){cmd_param=sprintf("%s%s%s",cmd_param,sep,$i);};  printf("%s %s %f %f %s %s\n", $2, $1, 100*($6/MB)/mem, $6/MB, $11, cmd_param);}' f_list=$f_list sep=$sep pid="$pid" mem=$mem MB=$MB |sort|uniq|awk '{gsub(sep," ",$6); printf("%d\t%s\t%5.2f\t%5.2f\t\033[2m%s %s\033[0m\n", $1, $2, $3, $4, $5, $6)}' sep=$sep| sort -b -k3rn,3 | head "-$top"
echo "================================================================"
if [ $mem -ge $MB ];then
	p_mem=$(awk -v mem="$mem" -v MB="$MB" 'BEGIN { print mem/MB }')
	unit="GB"
else
	let "p_mem=$mem"
	unit="MB"
fi
echo $p_mem $unit| awk '{printf("\033[1;34m Total memory :\t%.2f %s\n", $1, $2)}'
ps u $user | awk '{ memory = memory + $6/MB }; END { printf(" Total usage  :\t%5.2f MB (~ %5.2f %% of physical memory)\033[0m\n", memory, 100*memory/mem) }' mem=$mem MB=$MB
echo "================================================================"

About Eugen Mihailescu

Always looking to learn more about *nix world, about the fundamental concepts of arithmetic, algebra and geometry. I am also passionate about programming, database and systems administration.
This entry was posted in linux, shell and tagged . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s