マシンを再起動した後、スクリプトを続行する方法は?


18

私はbashでシェルスクリプトを書いています。スクリプトのある時点で、続行する前にマシンを再起動する必要があることを検出します。以下を発行します。

sudo reboot

マシンが復旧すると、このスクリプトで必要な作業がさらにあります。このスクリプトで作業を続行するために何かを構成するにはどうすればよいですか?

次の再起動時に実行されるようにシェルスクリプトを記述できる場所があると想定しています。そのような場所はどこですか?cronには@rebootディレクティブがあります。また、Apacheなどのサービスは、起動時に起動時に起動されることも知っています。どちらかが適切なメカニズムでしょうか?もしそうなら、どのようにトリガーされますか?

このスクリプトは、再起動のたびに実行されるのではなく、1回実行するだけで済みます。そのため、次の再起動時に実行される場所に移動するか、実行後に自身を削除する必要があります。

この質問では、再起動後にアプリケーションの状態を保存する方法について尋ねられます。私のスクリプトにはあまり状態がないので、それを管理できます。次回の再起動後にこのスクリプトで何かを実行させる方法を知る必要があるだけです。

私の特定のバージョンはUbuntu Linux 14.04です。元のスクリプトは、システム管理者がコマンドラインで起動します(cronから実行するのではありません)。


スクリプト内の再起動は、回避できない場合にのみ使用してください。たとえば、新しいカーネルのインストール。再起動せずにあなたの仕事ができると確信しています。リブートが必要な理由を指定できますか?
カオス14

1
このスクリプトは、新しいカーネルをインストールします(または、そうする可能性のあるaptアップグレードを呼び出します)。また、再起動を行う前に実際に再起動が必要かどうかも確認します。
スティーブンオステルミラー14

「スクリプト内での再起動は、回避できない場合にのみ使用してください。」-@chaosなぜですか?
ジョンレッド

回答:


16

システムでは、実際に永続的なのはファイルのみです。それはほとんどあなたが使用すべきものです。以下は、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 defaultsstart起動時にアクションが実行されます。さて、更新スクリプトが再起動を要求するとき:

touch /var/run/rebooting-for-updates
sudo reboot

このソリューションを使用すると、更新スクリプトを2つの部分に分割できます。

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ルート権限が必要です。

ファイルを使用しない場合(Stephen Ostermillerのコメントより):

getoptsユーティリティに精通している場合は、ファイルの代わりにオプションを使用できます。initスクリプトで、次を使用してスクリプトを呼び出します。

/path/to/update/script -r

スクリプトで、ファイルではなくオプションを確認します。オプションを指定せずにスクリプトを1回呼び出すと、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これを1回限りのジョブ(別のコメントから)に保つための呼び出しでスクリプトを編集しました。


2
呼び出しが簡単かもしれません/path/to/update/script --after-rebootから/etc/init.d/myupdateの存在に頼るのではなく/var/run/rebooting-for-updates。次に、直接実行する場合と起動時に呼び出す場合に、異なる引数を使用します。
スティーブンオステルミラー14

良いもの、オプションについては考えませんでした。編集させてください;)
ジョンWHスミス14

1
また、これは1回限りの作業なので、おそらくスクリプト自体にupdate-rc.d myupdate defaultsand を追加するupdate-rc.d myupdate removeだけでなく、/etc/init.d/myupdateファイルの書き込みや削除を行い、ファイルが残らないようにします。
スティーブンオステルミラー14

これを実装しましたが、うまく機能します。私が追加する他の唯一のことは、私のDebianベースのシステムが次のINIT INFOセクションに追加項目を必要とすることです:wiki.debian.org/LSBInitScripts
Stephen Ostermiller 14

本当にシンプルにしたかったのです;)適切なinit.dの作成には少し時間がかかりますが、さらに情報が必要だったのはうれしいです。これらのスクリプトは非常に便利です。
ジョンWHスミス14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.