• Posted on: Jan 5, 2009
  • Tag:
  • Reactions: 4

> Shutting down linux if a specific process is idle

I built myself a mini-itx linux server that I use as backup and testing platform. To save the planet I forced the small PC to automatically turn off at night, but I wanted to keep it alive if certain processes were still running.

Checking if a process is present is pretty trivial.

ps aux | grep processname

But if you want to monitor daemonized processes you can’t just check if they are present (they are always running in background), you need to verify the actual CPU usage for those processes. I thought it was a pretty basic feature but I couldn’t find anywhere a script that checks the CPU usage of a specific process, so I had to study a little of sh scripting.

A little disclaimer. I’m not a linux/terminal/sh/whatever guru. The script I’m showing you is probably dumb but it works for me.

ps returns the CPU usage of a process since it was first executed, so we can’t use it to check if a process is consuming CPU cycles in a specific moment. top instead returns a nice list of active processes.

Say you want to check if transmission (bittorrent client also available in cli/daemon mode) is actually downloading something. Create a new file with your text editor of choice and type the following:

#!/bin/sh

echo -n "Checking Transmission... "
CPUUSAGE=`top -b -n10 -d3 | grep transmiss | cut -c42-45 | awk '{sum+=$0}END{print sum*10}'`

if [ $CPUUSAGE -gt 4 ]; then
  echo "Transmission is working (CPU $CPUUSAGE)"
  exit 1
fi
echo "Transmission is idle (CPU $CPUUSAGE)"

echo "Server is splitting the atom, shutting down"
/sbin/shutdown -hP now
exit 0

All the magic happens on line 4

CPUUSAGE=`top -b -n10 -d3 | grep transmiss | cut -c42-45 | awk '{sum+=$0}END{print sum*10}'`

top -b -n10 -d3 runs top in batch mode 10 times every 3 seconds.

grep transmiss filters the processes whose name contains “transmiss”.

cut -c42-45 extracts from top the CPU usage (from the 42nd to the 45th character).

Lastly we are using the AWK programming language to sum the CPU usage in the time interval we are monitoring (30 seconds). We are also multiplying by 10 so we get an integer since (as far as I know) sh has some difficulties working with floats. So basically if the CPU usage is 0.4 we will get 4 as result.

At the end of line 4 we will have the variable CPUUSAGE filled with the CPU usage of the transmission process during 30 seconds gap.

If CPUUSAGE is greater than 4 (0.4) the script exits and shutdown is procrastinated (you may need to adjust this value).

All left to do is save the file as shutdown.sh, make it executable (chmod +x shutdown.sh) and execute it repeatedly from a root cron job.

The following is my crontab (sudo crontab -l):

*/10 0-5 * * * /home/matteo/bin/shutdown.sh >/dev/null 2>&1

It executes the shutdown script every 10 minutes from midnight to 5 (am). I noticed that many log files on the server are timed at 6:25 (debian system), so I set the motherboard to wake up the PC at 6:10. (PS: the server has a very low power consumption, 20w).

Note that, depending on the process you are monitoring, you may need to adjust the time interval. Transmission is quite stressful, so 30 seconds are enough to evaluate if the program is actually running, but you can check a longer (or shorter) time gap.

/Share the joy

/Reactions

    • Author: eugene
    • Posted on: 2009/02/06
    • At: 00:37

    the reason the syslog have a lot of 6:25 is daily cron execution (see /etc/crontab, change to what you need)
    nice blog you have.

    Reply
    • Author: Skami_18
    • Posted on: 2010/06/25
    • At: 13:58

    Verry cool :-)

    Reply
    • Author: Ole
    • Posted on: 2011/09/06
    • At: 22:40

    Hi!

    Great stuff! I’m using it already for my backup server. Is it possible to add more filters? – and if – how (of course)? – Could it be modified to check if a certain user is active?

    Thanks a lot!

    Reply
    • Yes, you should be able to check multiple services altering the regex (grep transmiss). Eg: grep “transmiss\|prog1\|prog2″.

      To check if an user is logged you may use “users” cmd.

      Reply

/Leave a reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>