0

nohup or die . . . UPDATED (02 Sep 16): shoptオプションのhuponexit とnohup の関係について

運用観点からも、意図しないプログラムの異常終了となりかねないBAD MANNERに気づく学びがある本話題ですが、

SSH 接続で時間の掛かるシェルスクリプトをバックグラウンドで走らせて帰りたいのに、
SSH 接続を切るとジョブが死んでしまいます。
SSH 接続に限らず目の前の OS からログアウトしたりターミナル エミュレータを終了しても同じ現象が起こります。

でも、この症状は正常です。

なぜなら、シェルスクリプトを起動した親プロセスは子プロセスの終了状態を監視してます。
ログアウトして親プロセスであるシェルが終了すると子プロセスはゾンビ プロセスとなってしまう為、
親プロセスとなるシェル(ログインシェル)は子プロセスであるバックグラウンド ジョブを kill ( kill -HUP ) します。

バックグラウンド ジョブを起動したプロセス(ログイン シェル)が子プロセスである該当のバックグラウンドジョブをハングアップ シグナル( HUP )によって終了させるからです。

■主なシグナル

シグナル名 シグナルID 説明
SIGHUP 1 プログラムを再起動するシグナルだ。 設定ファイルの再読み込みをさせる場合に使う事が多い。
SIGINT 2 割込み。プログラムを終了させるシグナルだ。 シェルからCtlr + Cで送信できるシグナルでもある。
SIGKILL 9 プロセスを強制的に殺すためのシグナルである。 SIGINTやSIGTERMが効かない場合でも、殺すことができる。
SIGTERM 15 プロセスを正常に終了させるシグナルだ。 killコマンドで送信するデフォルトシグナルである。 これが効かない場合はSIGKILLを使う。
SIGCONT 18 停止していたプロセスを再開する。fg、bg
SIGSTOP 19 一時停止。シェルからCtlr + Zで送信できるシグナルでもある。
SIGUSR1 ユーザ定義のシグナルで、プログラムによって意味が異なる。 ぱっと思いつくものではddで途中経過を表示させる用途に使われている。

■ nohup

バックグラウンドのプロセスをログアウト後も持続させる場合は、nohupコマンドを使います。
&はプロセスをバックグラウンド走行にし、実際はログアウトしても、走行が止まる事はないんです。
またエラーは$HOME以下のnohup.outに書き込まれます。

では これらを踏まえてnohupってなんなのか?

ご想像のとおり、nohupとは「No Hung Up」です。
そう。ハングアップシグナルによるプロセスダウンを回避できるコマンドです。

$ nohup mysqldump-hachim.sh &
[1] 25687

■ UPDATED (02 Sep 16) ■

bash、tcsh、ksh をデフォルト設定のまま使っていれば、

‘&’をつけてコマンドを実行するだけでログアウトしても処理は継続されます。

zshの場合はログアウト時もHUPシグナルが送信されますので、処理は終了します。

ちなみに、

$  shopt | grep hup
huponexit      	on

上記のように、huponexitが on に設定されているとログアウト時にHUPシグナルが送信されてしましますので、注意。
このような場合は、ログアウト後も処理を継続したい場合は、nohupを使います。

あるいは、
huponexit を無効化しましょう。

shopt -u huponexit

-s は set
-u は unset

■ disown

そもそもnohupしてなかった場合

ん。。なかなか終わらない。そそそも待ち状態で拉致があかない状況
ぬぁー!

そんな時は、
❶ C-zで一時停止
❷ psとかjobs -l で一時停止したプロセスのPIDやジョブ番号を調べる。
❸ これを引数にしてdisownを発行すれば大丈夫です。

プロセス番号を指定しないと現在のジョブを、
オプションで-a(–all)をつけると全てのジョブをデーモンプロセス化します。

$ disown 25687

これで気兼ね無くお酒が呑める事でしょう。
ログアウトしてもプロセスは死なず、
プログラム(mysqldump-hachim.sh)が
完走するまでプロセスは生きつづける。

mysqldump-hachim.shが時間のかかるプログラムだということが判ったので、
次に計算させるときはあらかじめログアウト後もプロセスを生かしておきたい!
そんな場合はnohupをつけてプログラムを起動する。

nohup ./mysqldump-hachim.sh &

以上です。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です