Earlier quoted context omitted.
How do you express those things in a systemd timer? E.g. run something 4x per day, */6 in cron.
$ systemctl cat public-inbox-watch@.timer # /etc/systemd/system/public-inbox-watch@.timer [Unit] Description=Periodic fetch of public mailing list [Timer] # twice a day OnCalendar=*-*-* 5,17:35 RandomizedDelaySec=1h Persistent=true [Install] WantedBy=multi-user.target
Love systemd timers
121–130 of 309 posts
Re: Love systemd timers
#122We have used cron perfectly fine for decades and it served us well within its very clear limitations. But now obviously we were so blind and wrong all this time and the only true solution is of course systemd.
I am not the biggest fan of systemd, but today I will always reach for a systemd timer over cron simply due to the sheer amount of bad experiences I've had with cron. Hours upon hours wasted trying to troubleshoot crons that weren't working due to some stupid obscure issue, having to use dirty hacks to monitor for success or retry failed jobs.
A few years ago I was trying to run a very simple bash script with cron and the script just died halfway through for no reason. Nothing in logs, worked fine when run directly, but in cron it just stopped halfway through a loop. Never figured out the cause, just gave up and used a timer instead, which worked fine. Never touched cron again after that.
The ease and convenience of monitoring and troubleshooting alone are worth switching over.
Re: Love systemd timers
#123For what it's worth there are usually web apps popping up that can decipher goofy cron time/date incantations. [1] This one has a git repo in the top right, not my repo. Maybe clone it just in case their site goes away some day.
Re: Love systemd timers
#124I haven't used systemd timers enough to disagree, but > Ambiguous $PATH settings make cron script execution difficult to predict. What makes you say that? You can set the PATH right in the crontab. Is that harder to "predict" than it being set in /etc/bashrc, ~/.bashrc, ~/.profile, ~/.bash_profile, /etc/systemd/…, or wherever else? > You might feel cool knowing the scheduling grammar by heart I've used Linux since 19…
another benefit is having logs in one place for the job; cron's "send a mail when there is any amount of output text" is just annoying behaviour, but also only place to get the job output unless you redirect it somewhere. Also starting from timer vs just doing systemctl start job.service is the same so easier to debug
other than that the few improvements in how to specify run time have been pretty useful.
For example, setting timer as "persistent" will mean any run "lost" to machine powered off will just be ran next time after boot, so you can have job on your PC that is just "run backup at 2AM" and if you turn it off before that you get the backup done first thing in the morning
There is also both random, and fixed (depending on machine UUID) random delay so avoiding thundering herd problem with backups is also pretty convenient.
There is even option to wake a device for the job if necessary tho the problem of shutdown is left to the user. And picking whether to start counting to next timer from previous one or from the job's end.
What I would like also is to have job summary page ("hey this job was done X times but failed Y times") but that's probably better left to external tooling
> You can set the PATH right in the crontab. Is that harder to "predict" than it being set in /etc/bashrc, ~/.bashrc, ~/.profile, ~/.bash_profile, /etc/systemd/…, or wherever else?
There is* a common trap as the cron PATH is usually just /usr/bin:/bin so anything in /usr/local/bin, or in /sbin won't be there.
Re: Love systemd timers
#125We have used cron perfectly fine for decades and it served us well within its very clear limitations. But now obviously we were so blind and wrong all this time and the only true solution is of course systemd.
Has it actually served you well? Because it hasn't served me well at all. I am not the biggest fan of systemd, but today I will always reach for a systemd timer over cron simply due to the sheer amount of bad experiences I've had with cron. Hours upon hours wasted trying to troubleshoot crons that weren't working due to some stupid obscure issue, having to use dirty hacks to monitor for success or retry failed jobs.…
Once you learn that env in cron is not same as in your shell and once you learn to redirect output to loggers - it works just fine.
It would be a lie to say that I never debugged cron and sure it's annoying.
> and the script just died halfway through for no reason
Unrelated to cron. Bad script.
Re: Love systemd timers
#126I wish documentation for tools would explain their abstractions concepts in terms of its primitives.
Great post, thanks!
Re: Love systemd timers
#127I haven't used systemd timers enough to disagree, but > Ambiguous $PATH settings make cron script execution difficult to predict. What makes you say that? You can set the PATH right in the crontab. Is that harder to "predict" than it being set in /etc/bashrc, ~/.bashrc, ~/.profile, ~/.bash_profile, /etc/systemd/…, or wherever else? > You might feel cool knowing the scheduling grammar by heart I've used Linux since 19…
"You just put numbers aligned with the titles." That is not a fair summarization of their point because that is not the grammar. There's commas, slashes, asterisks, combinations, and then if you want randomization you need to put it in the command itself because cron can't do it. (Some crons can, but it's not a general capability of cron.) Writing a non-trivial cron spec is not easy.
This is generally my only real complaint about systemd. I don't care if it is too monolitic, written in C or whatever, I just want a straightforward syntax for straightforward operations. I'd like it if systemd could recognize if a .target file is a shell script and just do "the right thing". Perhaps it would make sense for a timer file to recognize cron syntax as well. Or at least allow for a kind of extensibility so that I can have it supported.
If systemd had a little more respect for existing conventions, I am pretty sure it wouldn't be so controversial. After all, system administrators like it because they use it all the time, but a regular, full-timer user like me, who only deals with it when something is broken or have to use it as a means-to-an-end to set something up, then all friction is annoying and bad UX. (And no, using Nix is not the solution)
Re: Love systemd timers
#128I haven't used systemd timers enough to disagree, but > Ambiguous $PATH settings make cron script execution difficult to predict. What makes you say that? You can set the PATH right in the crontab. Is that harder to "predict" than it being set in /etc/bashrc, ~/.bashrc, ~/.profile, ~/.bash_profile, /etc/systemd/…, or wherever else? > You might feel cool knowing the scheduling grammar by heart I've used Linux since 19…
The main nice thing about the environment in systemd is that it is standard and mostly a blank slate, whereas at least for me I was always getting bit by the fact that the environment in Crontab was completely different from say, the environment inherited by supervisord or sysvinit scripts. In systemd the actual unit that gets executed is the same regardless of what triggers it, so there is no gap. That does require…
Odd. This script
#!/bin/bash
set > /tmp/set.txt
when scheduled like so * * * * * $HOME/bin/testCronScript.sh
Produces this file in /tmp/set.txt which has had a handful of values (HOME, UID, etc) lightly redacted prior to posting here -to remove PII or for length- but its keys are entirely untouched: BASH=/bin/bash
BASHOPTS=
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_LINENO=([0]="0")
BASH_LOADABLES_PATH=/usr/local/lib64/bash:/usr/lib64/bash
BASH_SOURCE=([0]="/home/user/bin/testCronScript.sh")
BASH_VERSINFO=
BASH_VERSION=
DIRSTACK=()
EUID=13370
GROUPS=()
HOME=/home/user
HOSTNAME=hostname
HOSTTYPE=x86_64
IFS=$' \t\n'
LANG=en_US.utf8
LOGNAME=user
MACHTYPE=x86_64-pc-linux-gnu
OPTERR=1
OPTIND=1
OSTYPE=linux-gnu
PATH=/usr/bin:/bin:/usr/sbin:/sbin
PPID=1337
PS4='+ '
PWD=/home/user
SHELL=/bin/sh
SHELLOPTS=braceexpand:hashall:interactive-comments
SHLVL=1
TERM=dumb
UID=13370
USER=user
_=/home/user/bin/testCronScript.sh
Seems pretty clean to me. Even when I run this via /etc/crontab, rather than as a user cron job: * * * * * root /home/user/bin/testCronScript.sh
I get effectively the same results.Maybe your distro's default cron environment was bad, and you never bothered to check and unset the badness? I'd be surprised if they were unable to make the default environment for Timer Units to be bad.
Re: Love systemd timers
#129Earlier quoted context omitted.
"You just put numbers aligned with the titles." That is not a fair summarization of their point because that is not the grammar. There's commas, slashes, asterisks, combinations, and then if you want randomization you need to put it in the command itself because cron can't do it. (Some crons can, but it's not a general capability of cron.) Writing a non-trivial cron spec is not easy.
How do you express those things in a systemd timer? E.g. run something 4x per day, */6 in cron.
In cron, you basically have to either use your configuration management to generate those times, or have a random delay script running before the command
In systemd timers, it's just
OnCalendar=0/6:00:00
RandomizedOffsetSec=60m
and the offset generated will be stable for the job on a given machine (i.e. always same on this machine but different on others) so you will get nice uniform distribution of load.If you add
Persist=true
the job will also be run once if there was one or more scheduled runs when the machine was downRe: Love systemd timers
#130Earlier quoted context omitted.
Friend, you have changed my life
Is this one of those cases where at one point you had an error in the file and you figured it was down to spaces? You fixed that issue, it still didn't work but from that point you never thought to question the assumption. I find myself doing this sort of thing all the time..