长久以来,Linux 和 Unix 系统都非常容易在启动时运行命令。只需将您的命令添加到 /etc/rc.local
即可。但事实证明,在关机时运行命令要稍微复杂一些。
为什么要在计算机关机时运行命令?也许您想从数据库中注销机器或服务。也许您想将数据从易失性存储系统复制到永久位置。想让您的电脑在关机前在 Twitter 帐户上发布“#RIP 我!”吗?
此时我应该澄清一下,我谈论的是所谓的“一次性”命令,而不是停止守护进程。尽管如此,很容易将它们视为相同的方式。如果您熟悉 SysVinit,您可能会想,“哦,我只需创建一个 kill 脚本。” 例如,当您的系统退出运行级别 3 时,应该调用 /etc/rc.d/rc3.d/K99runmycommandatshutdown
。毕竟,这就是 /etc/init.d/
中的脚本停止的方式。
这是一个很好的猜测,但事实证明这是错误的。SysVinit 不会盲目地运行 kill 脚本。相反,它会查找(在 Red Hat 6 上)/var/lock/subsys/service_name
(这里的 service_name
将是 runmycommandatshutdown
)。因此,您必须稍微耍一些花招,并将您的脚本视为常规服务。下面的脚本给出了一个例子
#!/bin/sh
# chkconfig: 2345 20 80
# description: An example init script to run a command at shutdown
# runmycommandatshutdown runs a command at shutdown. Very creative.
LOCKFILE=/var/lock/subsys/
start(){
# Touch our lock file so that stopping will work correctly
touch ${LOCKFILE}
}
stop(){
# Remove our lock file
rm ${LOCKFILE}
# Run that command that we wanted to run
mycommand
}
case "$1" in
start) start;;
stop) stop;;
*)
echo $"Usage: $0 {start|stop}"
exit 1
esac
exit 0
将该脚本放入 /etc/init.d/runmycommandatshutdown
并使用 chkconfig on runmycommandatshutdown
启用它后,您的命令将在关机时运行。
systemd
所有这些都很棒,但是如果您运行的 Linux 发行版使用 systemd 而不是 SysVinit 呢?事实证明,使用 systemd 要简单得多。您只需将脚本放入 /usr/lib/systemd/system-shutdown/
中,这由 systemd-halt.service 处理。当然,如果您需要在特定顺序中管理依赖项(例如,如果网络堆栈已关闭,则无法发布推文),那么您可以编写 systemd 服务单元文件。例如
[Unit]
Description=Run mycommand at shutdown
Requires=network.target
DefaultDependencies=no
Before=shutdown.target reboot.target
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=mycommand
[Install]
WantedBy=multi-user.target
10 条评论