golobitch
golobitch

Reputation: 1334

Bash - Memory usage

I have a problem that I can't solve, so I've come to you.

I need to write a program that will read all processes and a program must sort them by users and for each user it must display how much of a memory is used.

For example:

user1: 120MB
user2: 300MB
user3: 50MB
total: 470MB

I was thinking to do this with ps aux command and then get out pid and user with awk command. Then with pmap I just need to get total memory usage of a process.

Upvotes: 0

Views: 5031

Answers (4)

Simon Polak
Simon Polak

Reputation: 1989

Here is my version. I think that Tim's version is not working correctly, the values in KB are too large. I think the RSS column from pmap -x command should be used to give more accurate value. But do note that you can't always get correct values because processes can share memmory. Read this A way to determine a process's "real" memory usage, i.e. private dirty RSS?

#!/bin/bash
 if [ "$(id -u)" != "0" ]; then
 echo "WARNING: you have to run as root if you want to see all users"
 fi
echo "Printing only users that current memmory usage > 0 Kilobytes "
all=0
for username in `ps aux | awk '{ print $1 }' | tail -n +2 | sort | uniq`
do
 pids=`ps aux | grep $username | awk -F" " '{print $2}'`
 total_memory=0
 for pid in $pids
 do
  process_mem=`pmap -x $pid | tail -1 | awk -F" " '{print $4}'`

  if [ ! -z $process_mem ] 
  then #don't try to add if string has no length
   total_memory=$((total_memory+$process_mem))
  fi
 done
#print only those that use any memmory
if [ $total_memory -gt 0 ]
then
 total_memory=$((total_memory/(1024)))
 echo "$username : $total_memory MB"
 all=$((all+$total_memory))
 fi
done
echo "----------------------------------------"
echo "Total: $all MB"
echo "WARNING: Use at your own risk"

Upvotes: 0

Tim Rijavec
Tim Rijavec

Reputation: 26

it's just a little update, users are automatically selected

#!/bin/bash
function mem_per_user {
    # take username as only parameter
    local user=$1
    # get all pid's of a specific user
    # you may elaborate the if statement in awk obey your own rules
    pids=`ps aux | awk -v username=$user '{if ($1 == username) {print $2}}'`

    local totalmem=0
    for pid in $pids
    do
        mem=`pmap $pid | tail -1 | \
            awk '{pos = match($2, /([0-9]*)K/, mem); if (pos > 0) print mem[1]}'`
        # when variable properly set
        if [ ! -z $mem ]
        then
            totalmem=$(( totalmem + $mem))
        fi
    done

    echo $totalmem
}

total_mem=0
for username in `ps aux | awk '{ print $1 }' | tail -n +2 | sort | uniq`
do
    per_user_memory=0
    per_user_memory=$(mem_per_user $username)
    if [ "$per_user_memory" -gt 0 ]
    then
       total_mem=$(( $total_mem + $per_user_memory))

       echo "$username: $per_user_memory KB"
    fi
done
echo "Total: $total_mem KB"

Upvotes: 1

Summer_More_More_Tea
Summer_More_More_Tea

Reputation: 13356

Try this script, which may solve your problem:

#!/bin/bash
function mem_per_user {
    # take username as only parameter
    local user=$1
    # get all pid's of a specific user
    # you may elaborate the if statement in awk obey your own rules
    pids=`ps aux | awk -v username=$user '{if ($1 == username) {print $2}}'`

    local totalmem=0
    for pid in $pids
    do
        mem=`pmap $pid | tail -1 | \
            awk '{pos = match($2, /([0-9]*)K/, mem); if (pos > 0) print mem[1]}'`
        # when variable properly set
        if [ ! -z $mem ]
        then
            totalmem=$(( totalmem + $mem))
        fi
    done

    echo $totalmem
}

total_mem=0
for i in `seq 1 $#`
do
    per_user_memory=0
    eval username=\$$i
    per_user_memory=$(mem_per_user $username)
    total_mem=$(( $total_mem + $per_user_memory))

    echo "$username: $per_user_memory KB"
done
echo "Total: $total_mem KB"

Best regards!

Upvotes: 1

nsfyn55
nsfyn55

Reputation: 15363

You can access the shell commands in python using the subprocess module. It allows you to spawn subprocesses and connect to the out/in/error. You can execute the ps -aux command and parse the output in python.

check out the docs here

Upvotes: 0

Related Questions