Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Introduction to Linux - A Hands on Guide
This guide was created as an overview of the Linux Operating System, geared toward new users as an exploration tour and getting started guide, with exercises at the end of each chapter.
For more advanced trainees it can be a desktop reference, and a collection of the base knowledge needed to proceed with system and network administration. This book contains many real life examples derived from the author's experience as a Linux system and network administrator, trainer and consultant. They hope these examples will help you to get a better understanding of the Linux system and that you feel encouraged to try out things on your own.
Click Here to receive this Complete Guide absolutely free.
Hi,
I'm trying to write a bash script that outputs the process using the most memory when total free memory is <20%.
So I need to read the memory usage in from /proc/meminfo and just do arithmetic on Memtotal and Memfree
An then output ps to a log
You could use (( )) for that. And any parts of the script where arithmetic expressions are allowed like in indices of variables, special arguments in special parameter expansion forms, etc.
I need to set it up as a scheduled job with cron to output the process using the most memory when memory usage goes over 80%.
I'll be back if I get stuck again thanks
Its homework so the more I can do without help the better
If it's homework, I'd suggest you look at the man pages for head and tail, and eliminate the unnecessary cat <file> | cmd from your code. That idiom should be reserved for situations where it's necessary, and it a really bad habit to use it unnecessarily.
#!/bin/bash
NUMCORES=$(grep "^core id" /proc/cpuinfo | sort -u | wc -l)
LOADAVG=`cut /proc/loadavg -d ' ' -f 1`
PERUSAGE=`echo $LOADAVG '/' $NUMCORES '* 100 '|bc -l`
PROCESSSTRING=$(ps axo pid,args,%cpu --sort -%cpu|head -n 2|tail -n 1)
DAY=`date +%d`
MONTH=`date +%m`
YEAR=`date +%Y`
if [ `echo PERUSAGE '>80'|bc -l` -eq 1 ];then
if [ ! -d "log" ];then
mkdir "log"
fi
cd "log"
if [ ! -d "$YEAR-$MONTH" ];then
mkdir "$YEAR-$MONTH"
fi
cd $YEAR-$MONTH
echo $PROCESSSTRING>>$DAY.log
cd ".."
fi
Turns out I was doing the wrong assignment but not too bad nearly got it finished, I just need to write code to delete the logs that are older than 14 days now, the rest of this code outputs a log showing the most CPU intensive process when the load is >80%
The test function includes numeric comparison operators (e.g.: -lt -le -eq -ge and -gt). So why pipe into bc to test if [ ${DAY} -gt 14 ] ? (Beware that a leading zero will make the number octal in both bc and test.)
There is a printf command (on most system) that can be used to format a number with leading zeros.
The form $(cmd) is usually preferred to `cmd`, although the effect is often the same.
TroubleBob1.sh
NUMCORES=4
LOADAVG=0.56
PERUSAGE=14.00000000000000000000
real 0m0.077s
user 0m0.005s
sys 0m0.080s
TroubleBob2.sh
NUMCORES=4
LOADAVG=0.56
PERUSAGE=14.00
real 0m0.106s
user 0m0.012s
sys 0m0.107s
<edit>
Note that I dropped the -l option from the bc command. That option is only necessary if you need transcendental functions, and it sets scale to 20.
</edit>
Last edited by PTrenholme; 04-18-2013 at 06:06 PM.
Congratulations on figuring it out. However, there's a lot of room for improvement in your code. In particular there are a lot of unnecessary external process calls.
I've taken the liberty of re-writing it the way I would've done it. I'll just post it as-is, and hopefully you can analyze it as a learning exercise.
Code:
#!/bin/bash
IFS=- read -r year month day time < <( date '+%F-%c' )
read loadavg _ </proc/loadavg
numcores=$( grep -c '^core id' /proc/cpuinfo )
perusage=$( bc <<<"$loadavg / $numcores * 100" )
printf -v perusage '%.f' "$perusage" #rounds it to the nearest integer
if (( perusage > 80 ));then
cd "$HOME/log" || { echo "Can't enter log dir. Exiting." ; exit 1 ;}
mkdir -p "$year-month"
ps axo pid,args,%cpu --sort -%cpu --no-headers |\
head -n 1 >> "$year-month/day.log"
if (( ${day#0} > 14 ));then
rm -rf $year-[1-$month] $year-0[1-$month]
cd "$year-$month"
(( day = day - 14 ))
rm -f [1-$day].log 0[1-$day].log
fi
fi
exit 0
Last edited by David the H.; 04-21-2013 at 01:49 PM.
Reason: minor corrections
I just recognized a small flaw in my previous script.
Code:
if (( day > 14 ));then
this will not work properly in days 08 and 09, since the zero-padded numbers will be treated as octal values and error out. It's a simple fix though. Just strip off the leading zero:
Code:
if (( ${day#0} > 14 )); then
I'm updating my previous post to correct this too.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.