1. toshihirock

    Posted

    toshihirock
Changes in title
+nohupを使ってsshログアウト後もシェルスクリプトを動かす
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,88 @@
+既にたくさんの人が同じような記事を書いていましたが、自分メモ。
+
+# 参考
+
++ [ログアウトしてもバックグラウンドジョブを継続する方法](http://www.codereading.com/nb/ignore-the-hangup-signal.html)
+
+# 結論
+
+以下のように`nohup`コマンドを使い、かつ`&`の指定によってシェルスクリプトをバックグラウンドで動かせば良い
+
+```bash
+$nohup ./batch.sh &
+```
+
+# sshログウアウトするとなぜ止まるのか
+
+sshログインしている状態でバックグランドでシェルスクリプトを実行すると、sshdのログインシェル(bash)の子プロセスとしてシェルスクリプトが実行されます。
+
+```bash
+# プロセスの親子関係を確認
+$pstree
+init─┬─agetty
+ ├─atd
+ ├─auditd───{auditd}
+ ├─crond
+ ├─dbus-daemon
+ ├─dhclient
+ ├─6*[mingetty]
+ ├─ntpd
+ ├─rngd
+ ├─rpc.statd
+ ├─rpcbind
+ ├─rsyslogd───3*[{rsyslogd}]
+ ├─2*[sendmail]
+ ├─sshd───sshd───sshd───bash───pstree
+
+
+# バックグラウンドで./batchを実行
+$./batch.sh &
+
+# batch.shはsshdの子プロセスのbashプロセスの子プロセスとして実行されている
+$pstree
+init─┬─agetty
+ ├─atd
+ ├─auditd───{auditd}
+ ├─crond
+ ├─dbus-daemon
+ ├─dhclient
+ ├─6*[mingetty]
+ ├─ntpd
+ ├─rngd
+ ├─rpc.statd
+ ├─rpcbind
+ ├─rsyslogd───3*[{rsyslogd}]
+ ├─2*[sendmail]
+ ├─sshd───sshd───sshd───bash─┬─batch.sh───sleep
+ │ └─pstree
+ └─udevd───2*[udevd]
+
+```
+
+上記の場合に、sshのログアウトを行うとbatch.shにハングアップシグナル(HUP)を送信し、そのタイミングでシェルスクリプトが終了してしまうからです。
+
+# nohupコマンドとは
+
+`nohup`コマンドを使うことで上記のようにHUPシグナルがシェルスクリプトなどに送信された時でも無視するようにすることができます。
+これによってsshログアウト後もシェルスクリプトの継続が可能です。
+
+なお、nohupコマンドで実行されたスクリプトの標準出力及び標準エラー出力はプログラムを実行しているディレクトリに`nohup.out`というファイル名で保存されます。ディレクトリに書き込み権限がなければ`$HOME/nohup.out`として保存されます。
+
+スクリプトで大量の標準出力、標準エラー出力がされる場合にはファイルが肥大化するので必要ないものは捨てるなり対処が必要です。
+
+# そもそもシグナルとは
+
+以下を参考にさせていただきました。
+
++ [シグナルと trap コマンド](http://shellscript.sunone.me/signal_and_trap.html)
++ [Ctrl+Cとkill -SIGINTの違いからLinuxプロセスグループを理解する](http://equj65.net/tech/linuxprocessgroup/)
+
+
+実行中のプロセスに対して、様々なイベントを通知するために利用されるもの。
+
+例えばあるプロセスを止めたい場合に`kill -KILL [ps number]`という感じでコマンドを使うことがあると思いますが、これも対象のプロセスにシグナル名KILL(9)を送信してプロセスを終了しています。
+同じようにCtrl+Cよってプロセスを中断したり、Ctrl+zによって終了したりすることもありますが、プロセスに該当するシグナルを送信して機能を実現しています。
+
+今回のHUP(シグナル番号1)もシグナルの一つとして存在し、sshログアウトタイミングでHUPシグナルがシェルスクプトに送信されますが、nohupコマンドを使っていればHUPシグナルを受け取っても無視する挙動にすることができ、処理を継続することができていました。
+
+