我想设置脚本和 systemd 计时器,以允许 24x7 将 8 个 RTSP 流转储到磁盘,以 15 分钟为一个块,每个块从一刻钟开始。
我从一个脚本开始进行 15 分钟的转储(我做了一些日期数学和设置,但我省略了):
#!/bin/bash
ffmpeg -hide_banner -loglevel error -i $1 -vcodec copy -t 900 -y $2
然后我为每个流调用这个:
#!/bin/bash
for i in `seq 1 8`; do
./dump-rtsp.sh rtsp://address/$i $i.mp4 &
done
我的计时器文件很简单:
[Unit]
Description=Dump streams
[Timer]
OnCalendar=*:0/15
[Install]
WantedBy=timers.target
我的服务有点新奇:
[Unit]
Description=Dump RTSP for 15 mins
[Service]
Type=forking
ExecStart=/path-to-script/dump-multi.sh
[Install]
WantedBy=multi-user.target
顺便说一句,我发现 dump-multi.sh 中的 & 仅在类型设置为 forking 时才有效。我想这是有道理的,尽管我仍然不明白为什么我们需要对这些事情如此明确(或者实际上是简单和一次性之间的区别)。但我离题了。
这似乎工作得相对较好,除了由于计时问题,我发现后续触发计时器不会启动服务,因为最后一次运行仍在运行,因为它还剩下一秒钟左右。这也是有道理的,我通过只转储 899 秒解决了这个问题。这有点像黑客,因为如果有什么的话,我想确保连续性并使磁盘上的文件稍微重叠。
我本质上希望 shell 脚本每 15 分钟运行一次,没有如果,没有但是。这在 Systemd 中可能吗?也许可以选择允许单位多次触发?我的下一个方法是创建一组具有不同名称(可能使用模板)的两个服务来交替运行,但这似乎也有点hacky。
这更像是一个 cron 用例吗?我也很高兴完全使用不同的方法(例如让 shell 脚本本身执行 15 分钟循环)。
答案1
我的新计时器文件现在是:
[Unit]
Description=Dump streams
[Timer]
OnCalendar=*:%i:00
Unit=dump-rtsp@%i.service
[Install]
WantedBy=timers.target
我的服务不需要更改(因为我实际上不需要新参数),但重要的是在末尾用 @ 重命名它,以便可以调用多个实例。
然后您可以使用以下命令启动自定义计时器:
sudo systemctl enable [email protected]
sudo systemctl enable [email protected]
sudo systemctl start [email protected]
sudo systemctl start [email protected]
sudo systemctl start [email protected]
sudo systemctl start [email protected]