Skip to content

Linux script to automatically shutdown when load average is low

I’ve been using on-demand machines (similar to AWS EC2 and Google Cloud VM instances) to perform large computations. Those machines are both pay-as-you go and pretty expensive, so you want to terminate them as soon as your computations are done.

I’m sure there’s some fancy way, using tools provided by the cloud machine provider, to automatically shut down a machine that’s idle. But I thought, rather than looking for each vendor-specific, complicated (and likely billable) solution, I’d come up with a bash script. And here it goes:

while :
  load5M=$(uptime | awk -F'[a-z]:' '{ print $2}' | cut -d, -f1)
  echo $load5M
  if (( $(echo "$load5M < $threshold" | bc -l) )); then
    sudo shutdown now
  sleep 5

It's an infinite loop, with a 5 seconds pause, which gets the load average over the last 5 minutes, displays it, and if it's lower than the defined threshold of 0.5 (that's half a CPU core), immediately stops the machine. Simple enough, apart from the 2 magic lines needed to get the load average and to do a comparison between 2 floats (I found that surprisingly tougher than comparing 2 integers!)

A little warning though: be sure to test it, to check that your provider doesn't automatically restarts a terminated machine. That's quite unlikely, but it would be a shame ^^

Update 2021-10-04

I recently tried that on Debian, and I had an error about "bc not found", so I had to sudo apt-get install bc.
I'm still getting a weird 0: not found on the same line... And it doesn't work. So, turns out it might be Ubuntu-only somehow (I'm using it on Ubuntu 20.04 LTS, in case the version matters too)

Posted in Linux.

4 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Charlie says

    Thank you very much for sharing it! It is precisely what I was looking for!!

  2. Markus says

    Hello & another ‘Thank You’!
    After testing the seemingly only readily available tool (‘autopoweroff’), which did not work for me, I found your script and managed to adapt it to european systems, where ‘uptime’ returns processor loads as comma separated floats with decimal commas instead of decimal points…
    Works flawlessly (if there are mistakes, please let me know) on two headless systems I built: a small WebDav server, which starts up when addressed from the internet (I didn’t want it to run idle 99.9% of time, also for security concerns) and a small multimedia server (…don’t want to get up from the sofa to turn it off when finished watching movies :-)).
    I’m not a programmer and far from being a Linux expert, so I’m a little proud of it.
    Here’s how I did it:

    # autoshutdownbyload
    # does, what its name implies, adapted for european systems, where 'uptime' returns
    # processor loads as comma separated floats with decimal commas instead of decimal
    # points...
    while :
      load5M=$(uptime | awk -F'[a-z]:' '{ print $2}' | sed s/,//g | cut -b6-8)
      echo $load5M
      if [ $threshold -gt $load5M ]
        sleep 120
        shutdown now
      sleep 20
    • patheticcockroach says

      I’m pretty sure I did try that if [ $stuff -gt $otherstuff ] in my attempts to get the comparison working, but in my case it didn’t work. Bash is so mysterious to me…

      • Markus says

        It seems that comparing integers is much simpler than comparing floats…
        I was literally forced to do it that way because the output before piping to ‘sed’ was like this:
        0,89, 0,54, 1,44. ‘cut’ takes the commas as separators, therefore the -f option did not work. I had to eliminate all commas, which led to three integers. The 5min load value was then cut by the position of the three characters because ‘cut -f’ does not interpret the blanks between the numbers as separators…
        Think it would have been more complicated, if the output of ‘uptime’ had been like this:
        0.45, 0.76, 0.67 – with commas AND decimal points….
        I’m happy with the result!

Some HTML is OK

or, reply to this post via trackback.

Sorry about the CAPTCHA that requires JS. If you really don't want to enable JS and still want to comment, you can send me your comment via e-mail and I'll post it for you.

Please solve the CAPTCHA below in order to fight spamWordPress CAPTCHA