一次性服务
Type=oneshot 用于那些只需要执行一次性动作而不需要持久运行的单元,例如文件系统检查或者清理临时文件。
此类单元,将会在启动后一直等待指定的动作完成,然后再回到停止状态。下面是一个执行清理动作的单元:
[Unit]
Description=Cleanup old Foo data
[Service]
Type=oneshot
ExecStart=/usr/sbin/foo-cleanup
[Install]
WantedBy=multi-user.target
注意,在 /usr/sbin/foo-cleanup 执行结束前,该服务一直处于'正在启动中'的状态,而一旦执行结束,
该服务又立即变为'停止'状态,也就是说,对于 Type=oneshot 类型的服务,不存在'活动'状态。
这意味着,如果再一次启动该服务,将会再一次执行该服务定义的动作。
注意,
在时间顺序上晚于该服务的单元,将会一直等到该服务变成'停止'状态后,才会开始启动。从.svg文件就可以看出oneshot的service执行时间较长,而simple的service可以后台执行,只有启动的很短的时间。下面红色的表示执行时间较长,是oneshot service。
Type=oneshot 是唯一可以设置多个 ExecStart= 的服务类型。多个 ExecStart= 指令将按照它们出现的顺序依次执行,
一旦遇到错误,就会立即停止,不再继续执行,同时该服务也将进入'失败'状态。
可停止的一次性服务
有时候,单元需要执行一个程序以完成某个设置(启动),然后又需要再执行另一个程序以撤消先前的设置(停止),
而在设置持续有效的时段中,该单元应该视为处于'活动'状态,但实际上并无任何程序在持续运行。
网络配置服务就是一个典型的例子。此外,只能启动一次(不可多次启动)的一次性服务,也是一个例子。
可以通过设置 RemainAfterExit=yes 来满足这种需求。
在这种情况下,systemd 将会在启动成功后将该单元视为处于'活动'状态(而不是'停止'状态)。
RemainAfterExit=yes 虽然可以用于所有 Type= 类型,但是主要用于 Type=oneshot 和 Type=simple 类型。
对于 Type=oneshot 类型,systemd 一直等到服务启动成功之后,才会将该服务置于'活动'状态。
所以,依赖于该服务的其他单元必须等待该服务启动成功之后,才能启动。
但是对于 Type=simple 类型,依赖于该服务的其他单元无需等待,将会和该服务同时并行启动。
下面的类似展示了一个简单的静态防火墙服务(simple-firewall.service):
[Unit]
Description=Simple firewall
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/simple-firewall-start
ExecStop=/usr/local/sbin/simple-firewall-stop
[Install]
WantedBy=multi-user.target
因为服务启动成功后一直处于'活动'状态,所以再次执行"systemctl start simple-firewall.service"命令不会有任何效果。
[xiatian@hzling42 network-config-10g-if]$ vim
config_10g_if.service
[Unit]
Description=Configure Networking Interfaces
# List of all the interfaces we need before we run this script
Requires=sys-subsystem-net-devices-k2ax\x230.device
After=sys-subsystem-net-devices-k2ax\x230.device
Requires=sys-subsystem-net-devices-k2bx\x230.device
After=sys-subsystem-net-devices-k2bx\x230.device
Requires=sys-subsystem-net-devices-k2cx\x230.device
After=sys-subsystem-net-devices-k2cx\x230.device
Requires=sys-subsystem-net-devices-nic0\x230.device
After=sys-subsystem-net-devices-nic0\x230.device
Requires=sys-subsystem-net-devices-nic0\x231.device
After=sys-subsystem-net-devices-nic0\x231.device
Requires=sys-subsystem-net-devices-nic1\x230.device
After=sys-subsystem-net-devices-nic1\x230.device
Requires=sys-subsystem-net-devices-nic1\x231.device
After=sys-subsystem-net-devices-nic1\x231.device
# If this script fails, we might not have communications
# to the LCP. So reboot the system
OnFailure=emergency.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/systemd/scripts/config_10g_if.sh
CPUAffinity=0 1 2 3 4 5 5 6 7 8 9 10 11 12 13 14 15
[Install]
# Just in case nothing triggers network.target, make sure we still run this
WantedBy=multi-user.target
WantedBy=network.target
"oneshot"(未设置 ExecStart= 时的默认值)与"simple"类似,不同之处在于该进程必须在 systemd 启动后继单元之前退出。
此种类型通常需要设置 RemainAfterExit= 选项。