我想实现一个类似于以下的场景:
每天 XX:00 都会启动一项伞式服务,例如 daily_tasks。
当服务启动时,其他可以并行运行的服务也会启动,例如备份、清理、some_stuff
所有这些完成后,将运行另一个服务,例如卸载驱动器、关闭。
现在我知道partOf
并且我可以实现前两个部分:伞服务和孩子服务。但我不知道如何才能发现所有服务都已完成并启动另一项服务或另一项伞式服务。当我创建一个简单的空的伞服务它不知道孩子进程并将继续无限期地运行。
我很感激任何想法,即使意见是 systemd 不是设计来处理这个问题的!
非常感谢!
答案1
创建目标单位
首先创建一个.target
单元;这将作为我们的同步点。对于这个例子,让我们创建daily-task.target
:
[Unit]
Description=Run daily tasks
创建日常任务服务
对于并行运行的服务,创建(a)和 (b) 运行 的Type=oneshot
服务单元。例如:RequiredBy=daily-task.target
Before=daily-task.target
示例1.服务
[Unit]
Before=daily-task.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'sleep 10; date > /tmp/example1.txt'
[Install]
RequiredBy=daily-task.target
示例2.服务
[Unit]
Before=daily-task.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'sleep 15; date > /tmp/example2.txt'
[Install]
RequiredBy=daily-task.target
创建任务后服务
对于应该运行的服务后一切都已完成,创建 (a) 为RequiredBy=daily-task.target
且 (b) 运行的服务单元After=daily-task.target
。例如:
示例3.服务:
[Unit]
Description=Run after all daily tasks are complete
After=daily-task.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'sleep 10; date > /tmp/example3.txt'
ExecStopPost=/sbin/systemctl --no-block --user stop daily-tasks.target
[Install]
RequiredBy=daily-task.target
我们运行systemctl stop daily-task.target
此任务(通过
ExecStopPost
钩子)以便将目标移动到“停止”状态;如果我们不这样做,那么下次我们尝试systemctl start daily-task.target
什么都不会发生,因为目标已经启动了。
启用您的服务
systemctl --user enable example{1,2,3}.service
启动目标
为了运行我们的日常任务,我们启动目标:
systemctl --user start daily-tasks.target
如果发生这种情况时您正在查看日志,您将看到:
Sep 06 17:44:19 hostname systemd[5435]: Starting example1.service...
Sep 06 17:44:19 hostname systemd[5435]: Starting example2.service...
Sep 06 17:44:29 hostname systemd[5435]: Finished example1.service.
Sep 06 17:44:34 hostname systemd[5435]: Finished example2.service.
Sep 06 17:44:34 hostname systemd[5435]: Reached target Start daily tasks.
Sep 06 17:44:34 hostname systemd[5435]: Starting example3.service...
Sep 06 17:44:44 hostname systemd[5435]: Stopped target Start daily tasks.
Sep 06 17:44:44 hostname systemd[5435]: Finished example3.service.
由于我们创建的依赖关系与我们使用的
Type=oneshot
服务相结合,example1
并example2
运行
前 daily-tasks.target
被视为“已启动”,并example3
在其他一切完成后运行。