This should go quickly, but at least I can actually put some code on the blog for the first time in months…

An analog alarm clock on an end table

I’ve mentioned before that I have a script that I run overnight. I don’t publish the whole thing, because I have most of it tuned for my extremely specific use cases, but have extracted and published the most reusable bits of it as part of my Periodic Scripts repository.

For the blog, I find it especially important for that script to set a hacked-together alarm to remind me to rebuild and publish the blog when the next post goes out. Most reminders use a system sound to get my attention if I step away from the computer, ntfy to show a desktop notification, and at to set the time.

However, this scheme has a fatal-adjacent flaw.

If I set the publication time on the post too early, sleep in some morning, or otherwise end up in a situation where the system tries to set the alarm after I claimed that I wanted to get the post out, at always picks the next occurrence of the specified time. Therefore, waking up late sets the alarm for the following day.

Normally, I can catch that manually. When I notice that I’ve run late, I use atq and atrm to drop the incorrect reminders. If I don’t notice, though, then an alarm goes off the next morning and I have to remember why. But I shouldn’t need to do that.

When the issue came up, recently, and I also had some free time to look into it, I realized that I could compare the desired time with the time that the script runs, and make the decision then. I needed two key pieces of information. First, as I already knew, and you’ve probably seen come up on the blog before, the date command can take a +%s format to provide seconds since 1970. More surprising, though, if you only give date a time of day, it assumes that you want to parse the time as if it happens today. Combining the two, we get two timestamps, assuming that $time holds a string with the intended time of day, such as “6:28 AM,” “2:58 PM,” or “17:38.”

publish=$(date -d "${time}" "+%s")
now=$(date "+%s")

Once we have that information, I can compare the times and decide whether to set an alarm for later or trigger a notification now.

if [ $publish -gt $now ]
then
  ampm=$(date -d "${time}" "+%I:%M %p")
  ntfy send "${filename}" | at "${ampm}"
  echo "aplay /usr/share/sounds/sound-icons/prompt.wav" | at "${ampm}"
else
  ntfy send "Today's post (${title}) needs rescheduling..."
  echo aplay /usr/share/sounds/sound-icons/cembalo-2.wav
fi

I believe that the “sound icons” come installed by default with Debian-derived Linux distributions. Most of the sounds seem distinct enough and so rarely used that you can quickly recognize their new usage.

I told you that this would go quickly…


Credits: The header image is adapted from First photo by Nick Stenning, made available under the terms of the Creative Commons Attribution Share-Alike 2.0 Generic license.