5 ms·
My best practice with cron is to not use cron if possible. Systemd has timers with practically the same functionality and you'll never worry about: - Where to
by gjulianm 5y ago
My best practice with cron is to not use cron if possible. Systemd has timers with practically the same functionality and you'll never worry about:
- Where to put the logs, they just go into the system journal. Easy to check, and if you already have alerts/monitors/whatever for the journal any new job integrates trivially.
- Cron shell doing weird things.
- Easy switching on/off of each timer.
- Easy monitoring of when tasks are executed and the results.
- Jobs don't get started if there's one already running (I think)
- Better error messages when you mess the syntax.
- More possibilities for scheduling.
- Launching the job now if you need it to.
- traceroute66 5y ago> My best practice with cron is to not use cron if possible. Absolutely. I only randomly learnt about systemd timers thanks to a comment I read here on HN once. Since that point I've never looked back, its simply awesome. The main reason is its enabled me to remove a whole load of boilerplate from my scripts because systemd takes care of it for me. So my scripts are now shorter, more readable, and less prone to bugs. > Jobs don't get started if there's one already running Yes. This was the biggest selling point for me. On cron, I had a ton of boilerplate using all sorts of tricks to avoid the race condition of the script being run again before it had finished its prior execution. With systemd ? Remove the boilerplate, and, erm that's it. IIRC I don't think it even needs any special lines in your systemd unit file, it Just Works (tm).
- merpkz 5y agoWell, to be fair this article touches exactly that and solution is - use flock command before your cronjob, hardly a ton of boilerplate.
- traceroute66 5y ago> use flock command before your cronjob, hardly a ton of boilerplate Let's not go there shall we. Yes I know about flock, that's what I used. But if you are writing code correctly, you still end up with boilerplate. For a start, you need to write extra code to check the error status returned from flock. And then there's the overall point I was making. My "ton of boilerplate" referred to the overall boilerplate, i.e. flock was just one element, so then consider all the other boilerplate that was required to do all the other stuff that systemd does out of the box. Frankly, its a no-brainer. Systemd wins every time.
- KingMachiavelli 5y agoFor non-system administration stuff the best practice goes even further, actual applications probably shouldn't use either cron or systemd timers as a method of scheduling internal jobs. At most an application (if not already a service) should have a single timer on a short interval, but the application itself should internally manage jobs and scheduling. The last thing you want is state being stored in the OS files.
- eternityforest 5y agoOne of old school Linux's nastiest antipatterns is applications that unnecessarily depend on global configuration. It was everywhere, and it makes automated setup a major hassle. Lots of small self hosted things get written as if they were meant to be set up by IT professionals, and even then some of it is an unnecessary hassle even if it is meant for a commercial setting. What's even worse is pre systemd stuff that would put multiple unrelated services in one file. Systemd does it right because all your services are separate files with very little global anything that isn't inherently global. It's just like the LAMP stack. There are almost no PHP apps, just PHP code you can assemble into an app yourself with other daemons, usually with some subtle ways to get it wrong. Wheras more recent stacks are often unzip and run or apt-get and run with only a small amount of local configuration.
- bravetraveler 5y agoThis, so much this. Separating the schedule from the process might be an annoyance to newcomers... But I promise it's worth it It's two files to template instead of one line, but it fixes essentially every lesson we all learned with cron. $PATH being incomplete, locking, etc Another nice benefit is dependency handling. If your 'cron job' requires networking you have to write boilerplate code or let it fire/fail endlessly. Pray the processes don't linger/stack or otherwise make a mess. If a timer needs networking, set After= and Requires= to networking.target or whatever is appropriate for your distribution - and you're golden. Even better if the job acts against another actual systemd service. Using systemd-networkd you can tie the timers to specific interfaces. [but this handles NAT weirder than you're probably used to, if a host acts as a router prepare to adjust]
- pkulak 5y agoMy problem is that I always forget the complicated dance of creating a one-shot service file, then a timer of the same name, then enable then start. And is it --user? Where do they go again? I should write a little bash script that takes a name, a command, and a schedule and just sets it all up. Has anyone already done something like that?
- bingo-bongo 5y agoBeing able to schedule with a timezone is also great! Regards, someone living in a country with summer/winter-time
- BiteCode_dev 5y agoI'd love to learn more about this. Any good doc or tutorial ?
- gjulianm 5y agoThe Arch wiki is decent, provided you know how to work with systemd and making your own unit files https://wiki.archlinux.org/title/Systemd/Timers https://wiki.archlinux.org/title/Systemd/Timers
- upofadown 5y agoSystemd timers only work on one platform.
- bennyp101 5y agoyea, theres a whole load of funky stuff you can do with timers - if you can use systemd then totally use it. "Run this command the day before the last day of the month" - process some logs "Run this 15mins after the system boots" - connect to things once ready etc It is pretty cool
- soneil 5y agoand some stuff that sounds so simple but cron can't actually do - like "every 2 days".
- dschuck 5y ago0 23 star/2 star star insert_your_script_here.sh i.e. runs every two days at 11pm. or am i mistaken?
- dinom 5y agoThe problem is some months have an odd number of days thereby causing the job to run two days in a row. I'd consider offloading the work to the shell if you want to run things every other day, e.g.: * * * * * [ $(($(date +\%w) \% 2)) -eq 0 ] || echo skipped-a-day
- dschuck 5y agoDang, true. Didn't catch that. I think sometime I had set cron to run a script every day at a certain time and bypassed every other day with a simple .txt file. Top of my script was a simple if-clause, when alternate-day.txt is found, it will be removed and the script runs. If no .txt is found it will be created and the script exits. A bit lame, but it worked and was quick :)
- dinom 5y agoInterestingly, and on further consideration, using date with %w (as in the example I provided) suffers from the same problem, lol! Creating a file as you did should work nicely. Or a fair bit more arithmetic could be done using date's %s, not my cup of tea though. As mentioned, the next problem appears when the job takes longer than two days, which requires using flock. I often prefer to use mkdir instead of flock, provided your mkdir is atomic and POSIX compliant... which is usually the case AFAIK. E.G. mkdir a-lock-dir || exit;... rmdir a-lock-dir Ultimately I don't have too many complaints about cron. But, like anything, it has it's own quirks. Indeed a handy article.
- rhn_mk1 5y agoThe one reason I don't use systemd timers is that they don't have an automatic, reliable way to send me an email with their output.
- funcDropShadow 5y agoIf you happen to be on a Linux system with a properly configured mta (mail daemon), which you are if cron is able to send emails, you can just pipe the output of your command to sendmail
- rhn_mk1 5y agoIt would have been nice until extra logic comes in: cron doesn't send an email when there is no output. Which is exactly what I want! Error? I must know. Output? If I left any, then it's a notification, and I must know. No output? A maintenance task succeeded, nothing to report.
- pabs3 5y agoThere is a systemd-cron package in Debian that does that, except it only sends email on success.
- traceroute66 5y ago> The one reason I don't use systemd timers is that they don't have an automatic, reliable way to send me an email with their output. I can't remember the exact unit file syntax but you can define Before/After hooks, so you can point that to a script that emails people (or in my case pushes to a notification queue).