0

I want to set up scripts and systemd timers to allow 24x7 dumping of 8 RTSP streams to disk, in 15 minute chunks, each starting on the quarter hour.

I start with a script to do the dumping for 15 mins (I do some date math and setup which I've omitted):

#!/bin/bash
ffmpeg -hide_banner -loglevel error -i $1 -vcodec copy -t 900 -y $2

I then call this for each stream:

#!/bin/bash
for i in `seq 1 8`; do
  ./dump-rtsp.sh rtsp://address/$i $i.mp4 &
done

My timer file is simple:

[Unit]
Description=Dump streams

[Timer]
OnCalendar=*:0/15

[Install]
WantedBy=timers.target

My service a little novel:

[Unit]
Description=Dump RTSP for 15 mins

[Service]
Type=forking
ExecStart=/path-to-script/dump-multi.sh 

[Install]
WantedBy=multi-user.target

As an aside I found that the & in dump-multi.sh was only effective if the Type was set to forking. I guess that makes sense, although I still don't understand why we need to be so explicit about these things (or indeed the difference between simple and oneshot). But I digress.

This appears to work relatively well, except due to timing issues I find that a subsequent triggering of the timer won't start the service as the last run is still running, as it has a second or so left. This also makes sense and I've solved it by only dumping 899 seconds instead. This is a a bit of a hack, since if anything I would want to ensure continuity and have the files on disk overlap a little.

I essentially want the shell script to run every 15 mins, no ifs no buts. Is this possible in Systemd? Maybe an option to allow units to trigger multiple times? My next approach would be create a set of two services with different names (perhaps using a template) to run alternatively, but that also seems a bit hacky.

Is this more of a cron usecase? I'm also happy to use a different approach altogether (for example to have the shell script do the 15 min loop itself).

2
  • I think systemd decides not to start a unit that is already started. If you want to have several instance running concurrently, one idea is to template your service. Then start a different instance on each quarter hour. – Stewart Jul 2 '20 at 7:03
  • I was going to be efficient and run one on 00 and 30, and another at 15 and 45, but it's probably cleaner to do it four times. – Spammy Jul 2 '20 at 13:16
0

My new timer file is now:

[Unit]
Description=Dump streams

[Timer]
OnCalendar=*:%i:00
Unit=dump-rtsp@%i.service

[Install]
WantedBy=timers.target

My service didn't need to change (as I don't really need the new argument), but is important to rename it with an @ at the end so multiple instances can be invoked.

You can then start a custom timer with:

sudo systemctl enable dump-rtsp@.timer
sudo systemctl enable dump-rtsp@.service
sudo systemctl start dump-rtsp@00.timer
sudo systemctl start dump-rtsp@15.timer
sudo systemctl start dump-rtsp@30.timer
sudo systemctl start dump-rtsp@45.timer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.