0

I wrote a script to check on the battery and if it is below 5% notify the user.

The script is put to sleep for 1 minute after every check.

If I write the script in the following way, the cpu workload will rise to great extend:

#!/bin/sh

while true; do
  [[
    $(
      upower -i /org/freedesktop/UPower/devices/battery_BAT0 |
      grep percentage |
      grep -Poe  "\d*"
    ) -lt 5
  ]] &&
  notify-send "Battery below 5%" &&
  sleep 60
done

Do you know why the cpu went up? the notify command and the upower command dont free cpu resources

You can see in the image, that a lot of cpu resources are claimed. They will not be cleared.

If I write the script in a more conventional way, with simple if/else blocks, everything works as expected and the cpu will only go up for a short time in the beginning and after the sleep period is over:

while true; do
  if [[ 
      $(
        upower -i /org/freedesktop/UPower/devices/battery_BAT0 |
        grep percentage |
        grep -Poe  "\d*"
      ) -lt 5
     ]]; then
    notify-send "Battery below 5%"
  else
    sleep 60
  fi
done

Do you know why this behaviour is happening?

3
  • When you invoke notify-send "Battery below 5%" && echo Success does the output include the word "Success"? Commented Jul 13, 2022 at 18:30
  • sleep 60 is never triggering in the false case, as you combine all actions with && so it runs in an endless loop. Commented Jul 13, 2022 at 18:31
  • At some point, you will have this script running in the background, and you will want to terminate it. That will be much easier if you write your script as while sleep 60; do ... done. That way, to terminate the loop all you have to do is wait for the sleep 60 process to show up, and send a SIGTERM to its PID. while true loops are often notoriously hard to kill. Commented Jul 13, 2022 at 19:23

1 Answer 1

1

In the first version, you only sleep if the test is truthy and notify-send is called successfully; but not if the test is falsy. In the second version, you only sleep in the branch where the test was falsy, and notify-send was not called. Meaning you'd get the same issue when the battery is low with that latter version.

You should probably have the script sleep in either case, regardless of what the test result is. Minimally, change the && after notify-send to ; in the first version to break the relation between the two commands. I'd go with spelling the if-statement out, though, something like this:

#!/bin/sh
while true; do
  pct=$(
        upower -i /org/freedesktop/UPower/devices/battery_BAT0 |
        grep percentage |
        grep -Poe  "\d*"
      )
  if [ "$pct" -lt 5 ]; then
    notify-send "Battery below 5%"
  fi
  sleep 60
done

(Note that the [[ .. ]] conditional isn't a standard feature, and not all shells installed as sh in various systems support it.)

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.