More dynamic cronjobs

• ~600 words • 3 minute read

I remember learning about cronjobs in the early 2000s. I could tell the computer to go do something, on a recurring basis, forever, even when I wasn't there. They felt like magic!

We didn't have Crontab.guru or AI to ask for figuring out some of the more complex specifications. Just the man pages and good old-fashioned trial and error—mostly error in my case.

But while you could do fun, complex specifications of recurring intervals, you couldn't quite specify something quite as dynamic as "run this script every Tuesday at 7am unless it's the last Tuesday of the month..."

Or at least, you couldn't strictly through the crontab specification syntax. But I had a recent, mildly embarrassing epiphany that it's not hard at all to add arbitrary checks to your crontab to account for more complex and dynamic scenarios.

Want to run a script every Tuesday of the month at 7am except for the last Tuesday? That's easy—set up your crontab to run every Tuesday at 7am, but add a little check to make sure the next week is still part of the same month:

0 7 * * Tue [ "$(date -v+7d '+%m')" = "$(date '+%m')" ] && /path/to/your_command

If it's not part of the same month, that means we're on the last Tuesday for the month and the script won't run.

Note: The -v flag is for the macOS/BSD flavors of date. On Linux you'd want to use -d +7 days instead.

This really has nothing to do with cronjobs at all and everything to do with the POSIX "test" command which is the thing we're using with those square brackets. I'm used to seeing them and utilizing them in shell scripts, but for whatever reason I never thought to reach for that tool here in the crontab.

You could just as easily rewrite it like, skipping the bracket shorthand, which is probably easier to read:

0 7 * * Tue test "$(date -v+7d '+%m')" = "$(date '+%m')" && /path/to/your_command

It never crossed my mind until recently to add slightly more complex checks at the crontab level.

Other clever cronjob things you can do:

Holiday-only cronjobs

Maybe fetch a list of all the US Holidays for a given year and store them in a handy HOLIDAYS.txt file somewhere:

curl -s https://date.nager.at/api/v3/PublicHolidays/2025/US | jq -r '.[].date' > HOLIDAYS.txt

Now you can update your cronjob to run every Tuesday at 7am except on Holidays:

0 7 * * Tue ! grep -qx "$(date +%F)" HOLIDAYS.txt && /path/to/your_command

Or inversely, maybe run a holiday-only script that checks once a day

@daily grep -qx "$(date +%F)" HOLIDAYS.txt && /path/to/your_special_holiday_command

Only run on sunny days

The National Weather Service makes all kinds of fun data available (if you can find it...). How about a script that every hour, but only when the weather is clear?

@hourly curl -s "https://api.weather.gov/gridpoints/TOP/32,81/forecast/hourly" | jq -r '.properties.periods[0].shortForecast' | grep -qi clear && /path/to/your_command

Or maybe when the weather is cloudy?

@hourly curl -s "https://api.weather.gov/gridpoints/TOP/32,81/forecast/hourly" | jq -r '.properties.periods[0].shortForecast' | grep -qi cloudy && /path/to/your_command

Only run when there's something newsworthy

Or maybe we get in line with every-other-startup I'm aware of and throw AI at the problem, only running our script when the LLM gods have decided there is something newsworthy:

@hourly curl -s "https://news.google.com/rss?hl=en-US&gl=US&ceid=US:en" | llm --system "Reply strictly 'yes' or 'no'. Does anything in the news today suggest it is a good reason to run a script that I only want to send when the world is on fire and crazy and terrible things are happening?"  | tr -d '[:space:]' | tr '[:upper:]' '[:lower:]' | grep -qx yes && /path/to/oh_no
--

Published on Sunday, September 21st 2025. Read this post in Markdown or plain-text.

If you enjoyed this consider signing-up for my newsletter or hiring me