2

I have this udev rule that launches a script when the battery level is 5% or below:

$ cat /etc/udev/rules.d/90-lowbat.rules:

SUBSYSTEM=="power_supply", ATTR{status}=="Discharging", ATTR{capacity}=="5", RUN+="/opt/bin/battery-low.sh" 
SUBSYSTEM=="power_supply", ATTR{status}=="Discharging", ATTR{capacity}=="4", RUN+="/opt/bin/battery-low.sh"
SUBSYSTEM=="power_supply", ATTR{status}=="Discharging", ATTR{capacity}=="3", RUN+="/opt/bin/battery-low.sh"
SUBSYSTEM=="power_supply", ATTR{status}=="Discharging", ATTR{capacity}=="2", RUN+="/opt/bin/battery-low.sh"
SUBSYSTEM=="power_supply", ATTR{status}=="Discharging", ATTR{capacity}=="1", RUN+="/opt/bin/battery-low.sh"
SUBSYSTEM=="power_supply", ATTR{status}=="Discharging", ATTR{capacity}=="0", RUN+="/opt/bin/battery-low.sh"

This is the script:

$ cat /opt/bin/battery-low.sh:

#!/bin/bash
# Critical battery level (acpi reports it at 5%)
CRITICAL=5

battery_level=`acpi -b | grep -o [0-9]*% | sed s/%//`
if [ ! $battery_level ]
then
   exit
fi
if [ $battery_level -le $CRITICAL ]
then
   if acpi -a | grep 'off-line'
   then
      # First warning
      sudo -u andreas DISPLAY=":0.0" notify-send -u critical "GIMME POWER ... will shut down in 60 sec"
      sleep 60s
         if acpi -a | grep 'off-line'
         then
            # Second warning
            sudo -u andreas DISPLAY=":0.0" notify-send -u critical "... shutting down"
            sleep 2s
            # This is the path to systemctl in Debian
            /bin/systemctl hibernate
         fi
   fi
fi

When the power is the 5% or below the script is executed and I get the first warning.

However the last part of the script isn't executed. With the machine still unplugged I don't get the second warning and the computers doesn't hibernate.

Loads of things could of course be wrong with the script but the funny thing is that if I run the script with sudo ./battery-low.sh (when battery level is 5% or below and the machine is unplugged) everything works - I get the two warnings and the computer hibernates after approximately 62 sec.

Does udev launch the script in a way that is different from when if I launch the script manually? If yes, how so?

  • 1
    man udev >> RUN can only be used for very short-running foreground tasks.....Starting daemons or other long-running processes is not appropriate for udev. Try using a trigger script, i.e. RUN+="path/to/trigger.sh" where trigger.sh calls your script and exits (e.g. /opt/bin/battery-low.sh & exit) – don_crissti Oct 29 '14 at 0:37
  • 1
    Works! My bad for not checking if this was covered by the man pages. +1 for suggesting the trigger script. Will accept if you post comment as answer ... – MajorBriggs Oct 29 '14 at 1:26
  • @don_crissti, would you post it as answer. – user.dz Mar 5 '15 at 9:10
  • 1
    @Sneetsher + MajorBriggs: my suggestion above is just a popular hack; now with systemd all over the place the proper way to do it would be via ENV{SYSTEMD_WANTS}+= in the udev rule instead of RUN+=. I'll see if I have the time to play with it and post a proper solution. – don_crissti Mar 5 '15 at 15:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.