重新启动机器后如何继续脚本?

Ste*_*ler 21 shell-script reboot

我正在用 bash 编写一个 shell 脚本。在脚本的某个时刻,它检测到机器需要重新启动才能继续。它发出:

sudo reboot
Run Code Online (Sandbox Code Playgroud)

当机器重新启动时,这个脚本需要做更多的工作。如何配置某些内容以继续在此脚本中执行工作?

我假设在某个地方可以编写一个 shell 脚本,以便在下次重新启动时执行。哪里有这样的地方?我看到 cron 有一个 @reboot 指令。我也知道诸如 Apache 之类的服务是由 upstart 在启动时启动的。其中任何一个都是合适的机制吗?如果有,如何触发?

这个脚本只需要运行一次,而不是每次重启。因此,它必须在下次重新启动时运行,或者在运行后能够自行删除。

此问题询问如何在重新启动后保存应用程序状态。我的脚本没有太多状态,所以我可以管理它。我只需要知道如何让这个脚本在下次重启后触发一些东西运行。

我的具体版本是 Ubuntu Linux 14.04。原始脚本由系统管理员在命令行上启动(而不是从 cron 运行)。

Joh*_*ith 20

在系统上,唯一真正持久的是文件。这几乎就是你应该使用的。这是使用 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
Run Code Online (Sandbox Code Playgroud)

如果您使用 激活它update-rc.d myupdate defaults,该start操作将在启动时执行。现在,当您的更新脚本要求重新启动时:

touch /var/run/rebooting-for-updates
sudo reboot
Run Code Online (Sandbox Code Playgroud)

使用此解决方案,您可以将更新脚本分为两部分:

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
Run Code Online (Sandbox Code Playgroud)

它将执行before_reboot代码部分,在 中创建一个文件/var/run,然后重新启动。启动时,脚本将再次被调用,但由于文件存在,after_reboot将被调用而不是before_reboot.

请注意,这update-rc.d需要 root 权限。

不使用文件(来自Stephen Ostermiller的评论):

如果您熟悉该getopts实用程序,您可能希望使用选项而不是文件。在 init 脚本中,使用以下命令调用脚本:

/path/to/update/script -r
Run Code Online (Sandbox Code Playgroud)

在您的脚本中,检查选项而不是文件。在没有选项的情况下调用您的脚本一次,init.d 将在启动时再次调用它,这次使用-r.

# Set AFTER_REBOOT according to options (-r).

if [ "x$AFTER_REBOOT" = "xyes" ]; then
    # After reboot
else
    # Before reboot
fi
Run Code Online (Sandbox Code Playgroud)

您将在此处找到有关选项处理的更多信息(仅适用于短选项)。我还通过调用来编辑我的脚本,update-rc.d以保持这是一次性的工作(来自另一条评论)。

  • 从`/etc/init.d/myupdate` 调用`/path/to/update/script --after-reboot` 可能更简单,而不是依赖于`/var/run/rebooting-for-updates `. 然后它在直接运行和在启动时调用时会有不同的参数。 (2认同)