5
#!/bin/bash

# Get the battery percentage for battery 0
battery0_percent=$(cat /sys/class/power_supply/BAT0/capacity)

# Get the battery percentage for battery 1
battery1_percent=$(cat /sys/class/power_supply/BAT1/capacity)

# Threshold level
threshold=10

# Check if either battery is less than 10%
if [ "$battery0_percent" -lt "$threshold" ] || [ "$battery1_percent" -lt "$threshold" ]; then
    # Display a Zenity warning
    zenity --warning --text "Battery level is below 10% on one or both batteries!"
fi

This script sends a warning when one of my batteries is below 10%.

How can I run this script in the background, on a Linux system, so it will notify me when it has to?

4
  • What desktop environment are you using? Commented Sep 13, 2023 at 20:17
  • No DE. Only a wm. Commented Sep 13, 2023 at 20:44
  • 3
    In addition to the answers, you a missing a loop. The basic way to do this is enclosing the if in a while true; do [...]; sleep 1; done (1 for checking battery level every 1 second, might be an overkill). Otherwise, ./battery-script.sh & or using xinitrc will run on the background, but exit at the end of the script Commented Sep 14, 2023 at 6:17
  • 1
    Incidentally, depending on the session, you might be able to run something like notify-send --urgency=low --icon=battery "Low battery" "Battery level is below 10% on one or both batteries" instead of zenity to get a nicer display. Commented Sep 14, 2023 at 17:35

5 Answers 5

10

You have 2 ways to do this:

Add an ampersand after the command:

./battery-script.sh &

This will keep the command running even after you close the terminal, by spawning a subprocess within your shell.

If you want something that persists even after you log out the shell, you can add nohup before the command:

nohup ./battery-script.sh

This will also redirect the output of the command into a file called "nohup.out".

If you want to go even further and run this script at startup, you also have a few different options:

If you want this script to start up every time you start your display server:
With x11:

Add the line ./battery-script.sh & to the end of your ~/.xinitrc for the script to be run every time you start up x11(probably what you want in this scenario, given how you have a line for a zenity warning)
If you run wayland, it depends on your wm, with sway it's .config/sway/config.d/autostart_applications

If you want to run the script before your display server even starts, you can put the script in /etc/profile.d

2
  • 3
    Code in /etc/profile.d may run without a $DISPLAY being set, and it may run many times (each time a login shell is started), so I wouldn't put it there. Commented Sep 14, 2023 at 16:07
  • 1
    The script uses notify-send for a GUI notification, it won't work with no $DISPLAY, or without giving it access to the running X instance. Commented Sep 16, 2023 at 16:16
8

Create a systemd timer unit to have it run at regular intervals in the background.

/etc/systemd/system/my-batterywatcher.service

[Unit]
Description=my battery watcher

[Service]
Type=oneshot
ExecStart=/bin/bash /path/to/battery-watcher.sh

/etc/systemd/system/my-batterywatcher.timer

[Unit]
Description=my battery watcher

[Timer]
# run every minute
OnCalendar=*-*-* *:*:00
Unit=my-batterywatcher.service

[Install]
WantedBy=timers.target
systemctl daemon-reload
systemctl enable my-batterywatcher.timer
4
  • 1
    Will it be able to send a notification to the user? Commented Sep 14, 2023 at 13:39
  • 3
    Also consider making that an user unit instead if relevant, that way you won't need superuser powers. Commented Sep 14, 2023 at 14:17
  • 1
    Or run it from the crontab. (An older mechanism, less sophisticated, but more widely supported.) Commented Sep 14, 2023 at 23:49
  • 1
    How would this work with notify-send? Commented Sep 16, 2023 at 16:15
4

As already said, you can simply use & to run in background.

If you need to detach/attach, the way to go is to use or , that way, you can attach/detach a session as you need.

To run a command in background with screen:

screen -d -m -S NameOfTheSession ./script.sh

to list sessions available:

screen -ls

to re-attach:

screen -r NameOfTheSession
4

Several suggestions to run it in the background or as a conventional daemon, but this needs to run inside the session of the active user (since it wants to access the DISPLAY of the authenticated user).

Different X11 environments (not to mention Wayland) have different ways of starting up per-session services, but I believe the most portable one should be the XDG autorun mechanism. i.e. add (or link) the script in /etc/xdg/autostart/

0

What's wrong with a cron job ?

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.