Being an infallible human (hello fellow hoomans), I sometimes forget to update my system. I do tend to believe that due to using minimalist software, I’m at less risk to vulnerabilities, and many malware being made for x86 makes me even slightly less vulnerable, due to using an ARM platform.
Still, I want to at least have a way to check for updates. My desktop consists of Sway running on Void Linux. There is no way to automatically check for updates and get a notification from what I know. So back to the minimalist way, using whatever tools we have at our disposal. To the drawing board!
Previously, I have mentioned somewhere that I am just doing a simple crontab check every 6 hours, outputting a number into a text file and if it’s 0, sway will say “no updates,” otherwise “updates-available.” That worked for just a little time and I noticed I haven’t updated in a while, so I did not depend on the status bar to always be accurate. But a feature that is working sometimes is worse than a feature that doesn’t work at all, because it creates a dependence and a false sense of security on said feature.
So, here’s my simple solution to a pretty boring problem. Keep in mind that keeping the solution simple is a hard thing to do.
doas crontab -l -u root
0 6,12,18 * * * /usr/bin/sh /path/to/update-check.sh
cat /path/to/update-check.sh
/usr/bin/xbps-install -S
/usr/bin/xbps-install -Su --dry-run | /usr/bin/wc -l > /path/to/update-check-output.txt
So, up to this point, the root user’s crontab runs the update-check.sh script every 6 hours, but only 3 times a day (at 6, 12 and 18, not worth doing an additional check when I’m likely not there to see it). xbps-install -S
requires root privileges to update the internal db. Technically I could move the --dry-run command to my own user, as that doesn’t require root once the packages have been synced, but I’m keeping it like that for the sake of simplicity.
Thus far, either 0 or another number is getting written to ~/tmp/update-check-output.txt. If it’s 0, no updates, otherwise, updates are available.
grep status_command ~/.sway/config
status_command while ~/.sway/status.sh ; do sleep 1; done
cat ~/.sway/status.sh
#!/bin/dash
# The Sway configuration file in ~/.sway/config calls this script.
# You should see changes to the status bar after saving this script.
# If not, do "killall swaybar" and $mod+Shift+c to reload the configuration.
# Produces "21 days", for example
VAR_UPTIME_FORMATTED="$(uptime | cut -d ',' -f1 | cut -d ' ' -f4,5) ↑"
# The abbreviated weekday (e.g., "Sat"), followed by the ISO-formatted date
# like 2018-10-06 and the time (e.g., 14:01)
#(date "+%a %F %H:%M")
VAR_DATE_FORMATTED=$(date +'%a %Y-%m-%d %H:%M:%S')
# Get the Linux version but remove the "-1-ARCH" part
VAR_LINUX_VER="$(uname -r | cut -d '-' -f1) 🐧"
VAR_UPDATES_AVAILABLE=$(cat ~/tmp/update-check-output.txt)
[ ${VAR_UPDATES_AVAILABLE} -eq 0 ] && VAR_UPDATE_INFO="up-to-date ✅" || VAR_UPDATE_INFO="updates-available 🔄"
# Returns the battery status: "Full", "Discharging", or "Charging".
#VAR_BATTERY_STATUS=$(cat /sys/class/power_supply/BAT0/status)
# Volume
VAR_VOLUME=$(pamixer --get-volume)
if [ ${VAR_VOLUME} -eq 0 ]
then
VAR_VOL_INFO="${VAR_VOLUME} 🔇"
elif [ ${VAR_VOLUME} -gt 0 ] && [ ${VAR_VOLUME} -lt 40 ]
then
VAR_VOL_INFO="${VAR_VOLUME} 🔈"
elif [ ${VAR_VOLUME} -ge 40 ] && [ ${VAR_VOLUME} -lt 75 ]
then
VAR_VOL_INFO="${VAR_VOLUME} 🔉"
elif [ ${VAR_VOLUME} -ge 75 ]
then
VAR_VOL_INFO="${VAR_VOLUME} 🔊"
fi
VAR_CPU_THERMALS=$(cat /sys/class/thermal/thermal_zone0/temp)
VAR_CPU_TEMP="$((VAR_CPU_THERMALS/1000)).$(((VAR_CPU_THERMALS%1000)/10))'C 🔥"
echo cpu-temp=${VAR_CPU_TEMP} ${VAR_UPTIME_FORMATTED} ${VAR_LINUX_VER} ${VAR_UPDATE_INFO} vol=${VAR_VOL_INFO} ${VAR_DATE_FORMATTED}
The end result makes the sway status bar look something like this:
Keep in mind that .sway/status.sh runs every second, so the script ought to be able to execute and finish in less than a second
time ./.sway/status.sh>/dev/null
0m00.02s real 0m00.02s user 0m00.00s system
I prefer keeping it this way, but in theory, I could have a program or script running whenever I log in, check if sway is running and if the file contents have been modified, do a desktop notification, as opposed to changing my status bar, in order to remove clutter. For those who would desire such a thing, I just thought of simple solution number 2.
So, we keep the root user’s crontab in place, and the update-check.sh, but instead of running status_command every second, we can run entr
in our user’s shell rc profile (usually .bashrc).
So, at the end of .bashrc, add:
echo /path/to/update-check-output-file.txt | entr -p /path/to/special-sauce-script.sh &
entr is a neat little tool that monitors when a file changes when entr is running. We only want it to run whenever our user is logged in, so not worth putting it in crontab @ reboot. Besides, we still need to configure some stuff on the special-sauce-script, which should look like this:
#!/bin/sh
[ $(ps -ef | grep -c sway) -gt 0 ] && [ $(cat /path/to/update-check-output.txt) -gt 0 ] && notify-send "Updates are available 🔄"
For desktop notifications on sway, you will need to install mako
and if I’m not mistaken, have dbus running. So, entr is always running in the background and checks to see if the file we echoed into it gets modified. entr looks at the file itself, not the contents. So the script that entr executes when the file gets modified checks if sway is running, checks if the content of the file is bigger than 0 and if that’s true, does a send-notify (a desktop notification), which mako grabs through dbus and gives you a notification like this:

That’s basically it, an easy way to check for updates automatically and get a notification. Don’t forget whenever you update your system to echo 0 > update-check-output.txt
, so that the sway status bar will change. For the desktop notification, it doesn’t matter, because you only get a notification when the file changes.
Keep in mind I have not tested the thing with the bashrc, I just ran entr in a terminal, so YYMV. Do report back if it does or does not work, for others to know.