私はbashでシェルスクリプトを書いています。スクリプトのある時点で、続行する前にマシンを再起動する必要があることを検出します。それは発行します:
Sudo reboot
マシンが復旧すると、このスクリプトが実行する必要のある作業が増えます。このスクリプトで作業を続行するように何かを構成するにはどうすればよいですか?
次の再起動時に実行されるように、シェルスクリプトを記述できる場所があると想定しています。そのような場所はどこですか? cronに@rebootディレクティブがあることがわかります。 Apacheなどのサービスが起動時にupstartによって開始されることも知っています。それらのどちらかが適切なメカニズムでしょうか?もしそうなら、それはどのようにトリガーされますか?
このスクリプトを実行する必要があるのは1回だけで、毎回再起動する必要はありません。したがって、次のリブート時に実行される場所に移動するか、実行後に自分自身を削除できるようにする必要があります。
この質問 は、再起動後にアプリケーションの状態を保存する方法について尋ねます。私のスクリプトには状態があまりないので、それを管理できます。このスクリプトで次の再起動後に何かを実行する方法を知る必要があるだけです。
私の特定のバージョンはUbuntu Linux 14.04です。元のスクリプトは、(cronから実行するのではなく)システム管理者がコマンドラインで開始します。
システムでは、本当に永続的なのはファイルだけです。それはあなたが使うべきもののほとんどです。以下は、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
このソリューションを使用すると、更新スクリプトを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
にはroot権限が必要です。
ファイルを使用しない場合( 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回限りのジョブ(別のコメントから)に保ちました。