我们从最明显的东西开始 —— 设置定时器:
# stopminetest.timer -
[Unit] Description= 每天晚上七点停止 minetest.service -
[Timer] OnCalendar= *-*-* 19:05:00 Unit= stopminetest.service -
[Install] WantedBy= basic.target
这里棘手的部分是如何去告诉 stopminetest.service 去 —— 你知道的 —— 停止 Minetest. 我们无法从 minetest.service 中传递 Minetest 服务器的 PID. 而且 systemd 的单元词汇表中也没有明显的命令来停止或禁用正在运行的服务。
我们的诀窍是使用 systemd 的 Conflicts= 指令。它和 systemd 的 Wants= 指令类似,不过它所做的事情正相反。如果你有一个 b.service 单元,其中包含一个 Wants=a.service 指令,在这个单元启动时,如果 a.service 没有运行,则 b.service 会运行它。同样,如果你的 b.service 单元中有一行写着 Conflicts= a.service ,那么在 b.service 启动时,systemd 会停止 a.service .
这种机制用于两个服务在尝试同时控制同一资源时会发生冲突的场景,例如当两个服务要同时访问打印机的时候。通过在首选服务中设置 Conflicts= ,你就可以确保它会覆盖掉最不重要的服务。
不过,你会在一个稍微不同的场景中来使用 Conflicts= . 你将使用 Conflicts= 来干净地关闭 minetest.service :
# stopminetest.service -
[Unit] Description= 关闭 Minetest 服务 Conflicts= minetest.service -
[Service] Type= oneshot ExecStart= /bin/echo "Closing down minetest.service"
stopminetest.service 并不会做特别的东西。事实上,它什么都不会做。不过因为它包含那行 Conflicts= ,所以在它启动时,systemd 会关掉 minetest.service .
在你完美的 Minetest 设置中,还有最后一点涟漪:你下班晚了,错过了服务器的开机时间,可当你开机的时候游戏时间还没结束,这该怎么办?Persistent= 指令(如上所述)在错过开始时间后仍然可以运行服务,但这个方案还是不行。如果你在早上十一点把服务器打开,它就会启动 Minetest,而这不是你想要的。你真正需要的是一个确保 systemd 只在晚上五到七点启动 Minetest 的方法:
# minetest.timer -
[Unit] Description= 在下午五到七点内的每分钟都运行 minetest.service -
[Timer] OnCalendar= *-*-* 17..19:*:00 Unit= minetest.service -
[Install] WantedBy= basic.target
OnCalendar= *-*-* 17..19:*:00 这一行有两个有趣的地方:(1) 17..19 并不是一个时间点,而是一个时间段,在这个场景中是 17 到 19 点;以及,(2) 分钟字段中的 * 表示服务每分钟都要运行。因此,你会把它读做 “在下午五到七点间的每分钟,运行 minetest.service”
不过还有一个问题:一旦 minetest.service 启动并运行,你会希望 minetest.timer 不要再次尝试运行它。你可以在 minetest.service 中包含一条 Conflicts= 指令:
# minetest.service -
[Unit] Description= 运行 Minetest 服务器 Conflicts= minetest.timer -
[Service] Type= simple User= <your user name> -
ExecStart= /usr/bin/minetest --server ExecStop= /bin/kill -2 $MAINPID -
[Install] WantedBy= multi-user.targe
上面的 Conflicts= 指令会保证在 minstest.service 成功运行后,minetest.timer 就会立即停止。
(编辑:ASP站长网)
|