bash では huponexit
を ON にすると、シェルからログアウトした時に、ログインシェルの各ジョブにシグナル SIGHUP
を送信することができる。
手元の Ubuntu 12.04 だと、デフォルトは OFF
オプション操作
オプションの一覧表示
shopt
で一覧が表示される
$ shopt | grep huponexit huponexit off
オプションの切り替え
コマンド shopt
の -s/u
オプションがそれぞれ on/off に対応する。
s/u は set/unset のことらしい。
$ shopt -s huponexit; shopt | grep huponexit huponexit on $ shopt -u huponexit; shopt | grep huponexit huponexit off
Bash Manual : 4.3.2 The Shopt Builtin
http://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html
huponexit
が on になっているセッションでは、シェルログアウト時に各ジョブに対して SIGHUP
が送信される。
特定のジョブだけ SIGHUP シグナル送信を無効化したい
方法としては
- プロセスをジョブから外す
- 特定のジョブには
SIGHUP
シグナルを送信しない
の2通りがある。何れのケースでも disown
コマンドを利用する。
プロセスをジョブから外す
ジョブテーブルから外したいジョブ番号を disown コマンドの引数に指定する。
$ disown %1
特定のジョブには SIGHUP
シグナルを送信しない
SIGHUP
を受けとりたくないジョブ番号を disown
コマンドの -h
オプションに続けて引数に指定する。
この場合、対象ジョブはジョブテーブルには残ったままになる。
$ disown -h %1
Bash Manual : 3.7.6 Signals
https://www.gnu.org/software/bash/manual/html_node/Signals.html
実行例
バックグラウンドでプロセスを3つ走らせ
- 通常
SIGHUP
だけ除外- ジョブテーブルから除外
の3パターンを用意し、ログアウトして各プロセスが受け取るシグナルを確認。
バックグラウンドプロセスを作成
$ sleep 300 & [1] 9804 $ sleep 300 & [2] 9805 $ sleep 300 & [3] 9806 $ jobs [1] Running sleep 300 & [2]- Running sleep 300 & [3]+ Running sleep 300 & $ pstree -a -p init,1 ... ├─sshd,703 -D │ └─sshd,9534 │ └─sshd,9720 │ └─bash,9721 │ ├─pstree,9816 -a -p │ ├─sleep,9804 300 │ ├─sleep,9805 300 │ └─sleep,9806 300
bash プロセス から 3つのコマンドが spawn
されている。
disown コマンド実行
作成した3つのプロセスに対して
- ジョブ番号1はジョブテーブルから除外
- ジョブ番号2は
SIGHUP
だけ除外
$ jobs [1] Running sleep 300 & [2]- Running sleep 300 & [3]+ Running sleep 300 & $ disown %1 $ disown -h %2 $ jobs [2]- Running sleep 300 & [3]+ Running sleep 300 &
jobs
コマンドを実行すると、ジョブ番号1 は一覧から消えている。
signal を strace
別ターミナルを開き、作成した3つのプロセスに対して strace
でアタッチし、システムコール signal
を監視する。
sleep
を実行したシェルからログアウトすると disown
しなかったジョブ番号#3(pid:9806)には SIGHUP
が送信され、 disown
した残り2つのプロセスには SIGNUP が送信されない。
$ sudo strace -e trace=signal -p 9804 -p 9805 -p 9806 Process 9804 attached - interrupt to quit Process 9805 attached - interrupt to quit Process 9806 attached - interrupt to quit [pid 9806] --- SIGHUP (Hangup) @ 0 (0) --- Process 9806 detached Process 9804 detached Process 9805 detached
pid:9804, 9805 はログアウト後は親プロセスがいなくなるので(orphan)、init
プロセスにぶら下がる
$ pstree -a -p init,1 ... ├─sleep,9804 300 ├─sleep,9805 300
メモ
「プロセスに & をつけてバックグラウンド実行しログアウトすると、 SIGHUP
シグナルを受けてプロセスが終了する、、、」というのような記述を見かけたので、ちょっと調査した。
bash の場合は huponexit
オプションが有効になっていない限りは、そのようなことはないはず。