Using PS to output human readable memory usage for each process using AWK
I ran into a little issue: I wanted to list the memory usage of each process, but I wanted it to be output in human readable form (as in “df -h”). So, after a little Googling I found a forum thread which put the idea of using awk. A little bit later I had the solution:
Here’s what you see with normal ps:
$ ps u
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
kes1 12394 0.0 0.0 107356 2052 pts/1 Ss 08:15 0:00 -sh
kes1 12648 0.5 3.2 720808 527356 pts/0 S+ 08:16 0:16 /usr/lib64/R/bin/exec/R
kes1 13682 0.0 0.0 107360 2016 pts/3 Ss 08:18 0:00 -sh
Here’s what we want to see:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
kes1 12394 0.0 0.0 104.84Mb 2.00Mb pts/1 Ss 08:15 0:00 -sh
kes1 12648 0.7 3.2 703.91Mb 515.00Mb pts/0 S+ 08:16 0:16 /usr/lib64/R/bin/exec/R
kes1 13682 0.0 0.0 104.84Mb 1.97Mb pts/3 Ss 08:18 0:00 -sh
And here’s how we make that happen with awk:
ps u | awk '{
for ( x=1 ; x<=4 ; x++ ) { printf("%s\t",$x) }
for ( x=5 ; x<=6 ; x++ ) { if (NR>1) { printf("%13.2fMb\t",hr=$x/1024) }
else { printf("\t%s\t",$x) }
}
for ( x=7 ; x<=10 ; x++ ) { printf("%s\t",$x) }
for ( x=11 ; x<=NF ; x++ ) { printf("%s ",$x) }
print ""
}'
What does this awk script do?
There are a few different things going on here. First, we want to print out all the non-memory fields as tab-separated text. Second, we want to print out the memory as formatted kb and not bytes. Also, we want everything to line up. Finally, we want to print out the process name normally (using space and not using tab separation).
First, the script prints the first 4 fields:
for ( x=1 ; x<=4 ; x++ ) { printf("%s\t",$x) }
Then, we check to see if this is the header line or not. If it is the header line, then NR (the number of records read) will be 1. If it's not, then NR will be greater than 1. For the header, we print out the text (adding some more tabs to line things up). For the memory fields, we use printf to format the byte count as human readable text.
for ( x=5 ; x<=6 ; x++ ) {
if (NR>1) { printf("%13.2fMb\t",hr=$x/1024) }
else { printf("\t%s\t",$x) }
}
Finally, we print the remaining PS fields as before, but then we switch to space-delimited fields for the process name and arguments, making sure to add a newline at the very end.
for ( x=7 ; x<=10 ; x++ ) { printf("%s\t",$x) }
for ( x=11 ; x<=NF ; x++ ) { printf("%s ",$x) }
print ""
Nothing to it!
Like us on facebook!
Recent Posts
- Fujitsu Artificial Market Segmentation (or, how to make a Mac ScanSnap FI-5110EOXM work in Windows 8.1)
- MATLAB: Easily perform large batch jobs on multiple machines (without MATLAB Distributed Computing Server)
- Using PS to output human readable memory usage for each process using AWK
- Building SOAP services on Google App Engine in Java: Part 1 – The Servlet
- Eclipse RCP: Setting P2 repositories (update sites) programmatically (for when p2.inf fails).