Tips: (Linuxで)コンピュータの終了時にコマンドを実行する

Last-modified: 2015-03-01 (日) 22:49:25

USB接続時の自動実行ならこちらのページです。

 
 
 
 

初出 2006-10-7
最終更新 2015-2-24
役に立つシェルスクリプト群ページに記述している内容を分離させました。
 

systemdを採用したRHEL系最新ディストリビューション(CentOS等)用の方法(強引かつ単純)

(2015-2-24記述)
まだ私はsystemdについて殆ど何も知りません(普段RHEL系使ってないし)。そんな私でも(あなたでも)簡単に
思いつく手法を紹介します。

 

(1)/binに3つのシンボリックリンクを追加します。

# cd /bin
# ln -s systemd shutdown
# ln -s systemd reboot
# ln -s systemd halt
 

(2) デフォルトで存在する3つのシンボリックリンク /sbin/shutdown, /sbin/reboot, /sbin/halt をmvかrmで除去します。
※当然ですが、この作業を実施したからには下記の手順3まで必ず完了させて下さい。

 

(3)除去したシンボリックリンクの替りに以下のシェルスクリプトを設置します。
/sbin/shutdown

#!/bin/sh
. /sbin/hogehoge
exec /bin/shutdown "$@"

/sbin/reboot

#!/bin/sh
. /sbin/hogehoge
exec /bin/reboot "$@"

/sbin/halt

#!/bin/sh
. /sbin/hogehoge
exec /bin/halt "$@"

/sbin/hogehoge

if grep -q grub2 /var/log/yum.log; then
    exec >> /update-grub2.log
    exec 2>&1
    echo "-----------------------------------------"
    date
    set -x
    grub2-install --force `grub2-probe --target=device /boot`
    perl -i -pe "s/grub2/grub\(processed\)2/g" /var/log/yum.log
fi

おわかりでしょうが、/sbin/hogehogeの内容は、コンピュータ終了時に自動実行したい内容を具体的に
記したもの(この例の場合はgrub2のPBRへのセットアップ)です。シェルスクリプトの部品の形式をしたファイルです。

 

手順は以上です。作業時の権限や実行権限付加等の常識的な諸注意については説明を省略します。

 

この手法のミソを説明しておきます。
/bin/systemdコマンドが、呼び出し元のシンボリックリンクのパスではなく、basenameによってのみ動作を決定することを利用しています。つまり/bin/systemdは/sbin/shutdownから呼び出されたか、/bin/shutdownから呼び出されたかを区別しません。オリジナルの/sbin/shutdown -> /bin/systemdという経路を/sbin/shutdown -> /bin/shutdown -> /bin/systemdという経路に変更しても、/bin/systemd自体の動作は変わらないわけです。これを利用して経路の中間に任意の内容のシェルスクリプトを仕込むわけです。
(このような手法はLinuxを使う人にとって必須知識と思っておいた方がいいでしょう。似たような手法は至る所で使います。少なくとも私の場合)

 

例に示した/sbin/hogehogeの内容は、例としては実はかなり不適切です。
このファイルの内容は、grub2のstage1がPBRにセットアップされていて、且つgrub2自体がアップデートされた際に必要となるPBRへの再セットアップを(対応機構が用意されていないRedHat系OS上で)自動でおこなうものなのですが、普通に考えてgrub2パッケージよりsystemdパッケージの方がはるかに更新頻度が高いと思われます。仮にsystemdパッケージの更新を禁止する設定をおこなえば上記設定はずっと有効でしょうが、それをするぐらいなら、より更新頻度が低いと思われるgrub2パッケージの更新を禁止する設定をおこなうべきです。その場合当然、上記例の設定は不必要です。

(古い)RPM系ディストリビューション用の方法

(2014-3-8追記)この項はまだ残してありますが、2006年に記述したものです。当時と現在ではRedhat系も大きく変化しています。
RPM系ディストリビューション(Redhat、RHEL、Fedora、Vine、SUSE、CentOS...その他いろいろ)共通の方法です。

 

例えば、OS終了時にdisklessfunというユーザ名で/home/disklessfun/bin/bmc.sh"を実行したいとします。
その場合は、
/etc/rc.d/haltスクリプトの先頭あたりに(ヘッダーコメントの直後あたりに)

su - disklessfun -c "/home/disklessfun/bin/bmc.sh"

と記述しておくと終了時に自動で実行されます。
rootユーザで実行したい場合はコマンドをパス付きで記述するだけでOKです。

 

役に立つシェルスクリプト群ではWindowsとのマルチブート環境での使用例をとりあげています。

 

RPM系ディストリビューションはどんな終了の方法をとっても、(shutdown -r now,halt,init 0,init 6,poweroff,reboot,DEから...)/etc/init.d/haltスクリプトが呼び出されます。
このファイルはテキストなので自由に実行させたいコマンドを記述することができます。

Debian系ディストリビューション用の方法

Debian、Ubuntu共通の方法です。
この方法はファイル名、変数名を調整すればUNIX系汎用の方法です。

 

上記RPM系と同様の場合、
/etc/init.d/rcスクリプトの先頭あたりに(ヘッダーコメントの直後あたりに)

if test x$RUNLEVEL = x0 -o x$RUNLEVEL = x6 ; then
	su - disklessfun -c "/home/disklessfun/bin/bmc.sh"
fi

と記述しておくと終了時に自動で実行されます。
whileを使って終了と再起動で動作を変えることもできるでしょう。
(2009-01-29)dashで実行可能なように変更しました。

 

ご要望、ご意見、質問を下のフォームにどうぞ
(でもここより、掲示板書き込みフォームのページに書いて頂いた方が気づき易いと思います。)