49 18 * * * mpv ~/Musik/Donau.mp3
This command would play the Donau.mp3
file at exactly 6:49pm. How could I, for example, specify 6:49:50pm?
Super User is a question and answer site for computer enthusiasts and power users. It only takes a minute to sign up.
Sign up to join this communityUsing systemd
timer: https://wiki.archlinux.org/title/Systemd/Timers
You can specify seconds as well:
OnCalendar=Mon,Tue *-*-01..04 18:49:50
Or like this, 'hacking' crontab
:
49 18 * * * sleep 50; mpv ~/Musik/Donau.mp3
Don't expect this latter solution to be precise due to how cron
works.
49 18
will run at 18:49:00. But the idea is interesting :)
May 3 at 19:44
This command would play the "Donau.mp3" file at exactly 6:49pm.
Not exactly 6:49pm, precisely 6:49pm. This is an important distinction that actually partly explains why most cron implementations can’t do what you want.
At a high level, what crond actually does is sleep for approximately 60 seconds, then check what jobs need run and fire those off, then sleep again for approximately 60 seconds minus the amount of time it took to check and start jobs this cycle.
However, none of the mechanisms used for suspending a process for some amount of time on UNIX-like systems allow for an exact wakeup time. They only let you specify a lower bound on the wakeup time. For example, in C code, sleep(10);
will sleep for at least 10 seconds, but may sleep for longer than that (actually, it will almost always sleep at least one scheduling quanta longer than that). Usually the discrepancy is less than 200ms, but it’s entirely possible for it to be significantly longer if the system is heavily loaded or the process being woken up is exceptionally low priority.
For the usual case for crond of sleeping for 60 seconds, jitter of even a few seconds is generally insignificant, because it can just adjust how long it sleeps on the next cycle to compensate. If, however, it was trying to run things every second instead, jitter of more than about half a second would be enough to cause reliability issues and possibly miss events.
This then brings up the question of why systemd lets you specify timestamps down to the second for timer units. The reality is that it doesn’t actually schedule to that precision either. Systemd offers per-second resolution because it operates in a fundamentally different way from crond, instead of checking every cycle for jobs that need to run, systemd sets timers to be woken up when a job needs to run. On an idealized system with minimal timing jitter, this enables it to actually trigger things with that level of precision. In practice though, it’s not unusual on a busy system for timer units scheduled with that precision to be a second or two late.
How could i (for example) specify 6:49'50pm?
If you truly need that level of precision, the correct answer is to use a realtime OS for whatever you’re doing, not a time-sharing OS.
You can get close to this on a Linux system by running crond with a realtime scheduling priority, but doing so safely requires a significant amount of effort to ensure that the jobs don’t inherit that priority (which would run a nontrivial risk of them causing problems for anything else running on the system), but that still won’t let you pick exact times down to the second to run jobs at.
cron
that isn't built for this. It's certainly possible using a Python script (and nothing else except background tasks) under Debian on a Raspberry Pi 3. You can actually go far better. For human interaction 100ms is effectively the precision limit you need - easily doable. Pushing it further still, audio, it makes little sense to even define time increments less than about 100µs. Testing down to that level on a Pi3's GPIO showed jitter in increments of ~10µs (still better than a Win7 desktop)
sleep $(($(date -d "18:49:50" +%s) - $(date +%s))) && mpv ...