马尔普特是一个命令行实用程序,用于捕获流星 2 号卫星的数据。卫星每天在不同的时间经过头顶,我想使用 systemd 计时器以mlrpt
正确的参数开始。
我从从 API 获取的时间开始
startDate start_times end_times duration
1 2019-08-25 17:51 18:05 14
2 2019-08-25 19:31 19:45 14
3 2019-08-26 05:07 05:21 14
4 2019-08-26 06:47 07:01 14
5 2019-08-26 19:11 19:25 14
6 2019-08-27 06:27 06:42 15
7 2019-08-27 18:51 19:06 15
8 2019-08-28 06:07 06:22 15
9 2019-08-28 18:31 18:46 15
10 2019-08-29 05:47 06:02 15
11 2019-08-29 18:11 18:26 15
12 2019-08-30 05:27 05:42 15
13 2019-08-30 17:51 18:06 15
14 2019-08-30 19:31 19:45 14
15 2019-08-31 05:08 05:22 14
16 2019-08-31 06:48 07:02 14
17 2019-08-31 19:11 19:26 15
18 2019-09-01 06:27 06:42 15
19 2019-09-01 18:51 19:07 16
20 2019-09-02 06:07 06:23 16
21 2019-09-02 18:31 18:47 16
22 2019-09-03 05:47 06:03 16
对于每次想要运行 mlrpt 的格式mlrpt $startT-$stopT -t $durationMin
我从这个服务文件开始
~/.config/systemd/user/mlrpt.service
[Unit]
Description=Capture Meteor satellite data using mlrpt
DefaultDependencies=no
Wants=local-fs.target time-sync.target
After=local-fs.target time-sync.target
[Service]
Type=simple
ExecStart=/usr/local/bin/mlrpt $START_TIME-$END_TIME -t $DURATION
我如何设置计时器文件,以便它不仅mlrpt
在正确的时间启动,而且能够将正确的参数传递给实用程序(它们每次都不同)?我想我需要一个类似的模板
~/.config/systemd/user/mlrpt.timer
[Unit]
Description=Run mlrpt when a satellite is overhead
[Timer]
OnCalendar=
Persistent=true
[Install]
WantedBy=timers.target
但不知道下一步该去哪里。如果我有正确的计时器文件的示例,我就具备生成计时器文件的脚本技能。
答案1
对于这些一次性的、非重复性的任务,我认为我找到了更好的解决方案systemd-run
。对于列表中的第一个条目,我会编写一个脚本来运行systemd-run --user --on-calendar="2019-08-25 19:51" /usr/local/bin/mlrpt "17:51-18:05" -t 14
答案2
另一种方法是将多个元素组合在一个服务文件中(无计时器)。这些要素是:
“自重启”
Type=oneshot
服务,其EnvironmentFile=/path/to/mlrpt-textfile
指令读取单个卫星通道的 mlrpt 参数,编码为来自“mlrpt-textfile”的自定义 varenv。这些参数为 1) $START_TIME 和 2) $END_TIME(用于卫星传递),3) 传递 $DURATION,以及 4) $WAIT 直到下一次传递的时间。两个文本文件。例如,一个称为“mlrpt-list”,其中包含自定义 mlrpt 参数的完整列表,与包含 22 个条目的列表类似但不相同。另一个文本文件仅包含一个条目(这是上面提到的“mlrpt-textfile”)
一种机制(包括一个简单的脚本),从“mlrpt-list”开头读取第一个条目,将其复制到“mlrpt-textfile”,然后删除“mlrpt-list”中的第一个条目,并重复相同的过程按需,直到“mlrpt-list”中没有任何条目为止(注意:复制到“mlrpt-textfile”不应追加而是覆盖)。
现在,oneshot-service 文件应大致如下所示,将所有三个元素合并到一个工作解决方案中。使用 oneshot 的主要原因是它不仅能够容纳一个指令,而且能够容纳多个ExecStart=
指令。根据设计,这些ExecStart
指令是一个接一个地执行的。这使我们能够通过单个一次性服务单元来创建和执行上述“机制”。
# /etc/systemd/system/myservice.service
[Unit]
Description=my service Service
ConditionPathExists=/path/to/mlrpt-textfile # contains $START_TIME, $END_TIME, $WAIT,
# and $DURATION for a single pass
ConditionFileNotEmpty=/path/to/mlrpt-textfile
EnvironmentFile=/path/to/mlrpt-textfile
[Service]
Type=oneshot
ExecStart=/usr/local/bin/mlrpt $START_TIME-$END_TIME -t $DURATION
ExecStart=/bin/sleep $WAIT
ExecStart=/path/to/script # script copies one entry from mlrpt-list to mlrpt-textfile
ExecStopPost=/bin/systemctl restart myservice.service
[Install]
当然,这需要更多的细化(例如需要根据需要添加依赖项)。该脚本还应用于使服务在最后一次传递后失败,例如通过在最后一次传递后擦除“mlrpt-textfile”中的条目(以便ConditionFileNotEmpty
重新启动时失败)。