我正在用 bash 编写 shell 脚本。在脚本中的某个时刻,它检测到机器需要重新启动才能继续。它发出:
sudo reboot
当机器恢复运行时,该脚本需要执行更多工作。如何配置某些内容以继续执行此脚本中的工作?
我假设在某个地方可以编写 shell 脚本,以便在下次重新启动时执行它。哪里有这样的地方呢?我看到 cron 有一个 @reboot 指令。我还知道像 Apache 这样的服务是由 upstart 启动的。其中任何一个都是适当的机制吗?如果有的话,如何触发呢?
该脚本只需运行一次,而不是每次重新启动时运行。因此,它将必须转到仅在下次重新启动时运行的某个位置,或者能够在运行后自行删除。
这个问题询问如何在重新启动后保存应用程序状态。我的脚本没有太多状态,所以我可以管理它。我只需要知道如何让这个脚本在下次重新启动后触发某些内容运行。
我的具体版本是Ubuntu Linux 14.04。原始脚本由系统管理员在命令行上启动(而不是从 cron 运行)。
答案1
在系统上,唯一真正持久的就是文件。这几乎就是您应该使用的。这是使用 init.d 脚本的解决方案。
让我们考虑以下(简单)脚本/etc/init.d/myupdate
:
#! /bin/sh
### BEGIN INIT INFO
# Provides: myupdate
### END INIT INFO
PATH=/sbin:/bin:/usr/sbin:/usr/bin
case "$1" in
start)
/path/to/update/script
;;
stop|restart|reload)
;;
esac
如果您使用 激活它update-rc.d myupdate defaults
,该start
操作将在启动时执行。现在,当您的更新脚本要求重新启动时:
touch /var/run/rebooting-for-updates
sudo reboot
通过此解决方案,您可以将更新脚本分为两部分:
before_reboot(){
# Do stuff
}
after_reboot(){
# Do stuff
}
if [ -f /var/run/rebooting-for-updates ]; then
after_reboot
rm /var/run/rebooting-for-updates
update-rc.d myupdate remove
else
before_reboot
touch /var/run/rebooting-for-updates
update-rc.d myupdate defaults
sudo reboot
fi
它将执行before_reboot
代码部分,在 中创建一个文件/var/run
,然后重新启动。启动时,将再次调用该脚本,但由于该文件存在,因此after_reboot
将调用该脚本而不是before_reboot
.
请注意,update-rc.d
需要 root 权限。
不使用文件(来自斯蒂芬·奥斯特米勒的评论):
如果您熟悉该getopts
实用程序,您可能希望使用选项而不是文件。在 init 脚本中,使用以下命令调用脚本:
/path/to/update/script -r
在您的脚本中,检查选项而不是文件。在没有选项的情况下调用一次脚本,init.d 将在启动时再次调用它,这次使用-r
.
# Set AFTER_REBOOT according to options (-r).
if [ "x$AFTER_REBOOT" = "xyes" ]; then
# After reboot
else
# Before reboot
fi
您将找到有关选项处理的更多信息此处(仅适用于简短选项)。我还通过调用编辑了我的脚本,以update-rc.d
使其成为一次性工作(来自另一条评论)。