ので、ずっと実行し続けるための方法を探った。
参考:
ログアウトする(orネットワーク切れる)とき、コマンドを実行し続けたいとき、 以下の方法で、コマンドを実行する。
$ nohup コマンド &
nohupでコマンドを実行した場合は,ログアウトしてもプログラムを実行し続ける。 長い処理を行っており,席を外したいときなどに使用すると便利である。 ログアウトした後は,ジョブではなくプロセスとして管理することになる。 また,処理中に出力されたメッセージは”nohup.out”に保存される。”
※参考: ITpro記事_nohup
nohupでsshログアウトしても実行維持
nohupコマンドでsshログアウト時に送られるHUPシグナルによる バックグラウンドジョブのkillを行われないようにする
HUPシグナルについては以下の資料がとても参考になる 参考: http://qiita.com/yushin/items/732043ee23281f19f983
$ nohup sleep 5 &
標準出力などがある場合はデフォルトで
./nohup.out
というファイルに出力される。 以下のようにファイルを指定すれば、任意のファイルに出力できる。$ nohup echo test > test.txt &
nohup
コマンドが用いるのが一般的なようだ。また、
- シェルからバックグラウンドで処理を行うには?
nohup コマンド実行 &
を使う。- コマンド実行 =>
Ctrl-Z
=>disown
を使う。定番は前者だが、両者の違いは何なのか? disownとは一体何をするのか?
ジョブテーブル
- シェルはセッションに紐づくジョブテーブルを持っている。
- バックグラウンドジョブを登録している。
- (フォアグラウンドジョブは未確認。ソースを読むしかないか)
jobsビルトインコマンド
で一覧を参照可能。
- ここに見える限り、シェルのexit時に
SIGHUP
を送る。- この一覧にない場合、exit時に
SIGHUP
は送らない。- シェルオプションで
nohup
を指定した場合、ジョブテーブルに見えてもSIGHUP
を送らない。- ジョブテーブルから消すには、
disown
を使う。fg
やbg
でフォアグラウンド、バックグラウンド化できる。(monitorオプション有効時)
nohup
コマンド
SIGHUP
を無視した状態でプロセスを起動する。- シェルは終了時に
SIGHUP
を送るかもしれないが、届いても無視する。kill -SIGHUP
で直接送っても無視。disown
しない限りジョブテーブルに残る。fg
,bg
,disown
,Ctrl-Z
などを受け付ける。- フォアグラウンドジョブに付与した場合でも、
SIGHUP
を受け付けずに継続する。- (標準出力/エラー出力が端末の場合に nohup.out に出したりする)
- (尚、
nohup
を付けて実行すると、trap
ビルトインコマンドでもキャッチできない)
disown
コマンド
- ジョブテーブルから外れる。
fg
、bg
コマンドを受け付けず、jobs
で参照できない。- シェルの終了時に
SIGHUP
を送らない。SIGHUP
をkill -SIGHUP
などで直接送ると受け付ける。(nohup
しない限り)- (フォアグラウンドジョブ実行状態で自分に
disown
は打てないので、対バックグラウンド専用)シェルのhup/nohupオプション
- シェルの終了処理でジョブテーブルのジョブに対して
SIGHUP
を送るかどうか。
disown
でジョブテーブルから外れている場合はこれに関係なく送らない。- フォアグラウンドジョブでも
hup
オプションがセットされていれば、シェルの終了時にSIGHUP
を送る。
- 端末が切れた場合にフォアグラウンドジョブにはカーネルからも
SIGHUP
が送られる。上記と合わせて2回のケースがある。- 逆に言えば、シェルオプションで
nohup
にしても、フォアグラウンドのジョブ実行中のまま端末を切るとカーネルがSIGHUP
を送ってくる。
disown
というコマンドでも終了しないようにできるようだ。両者の違いを簡潔にまとめると、
nohup
SIGHUP
シグナルを受け付けなくする。SIGHUP
を無視するので動き続ける。SIGHUP
も無視する。disown
SIGHUP
は端末の job に対してのみ送られるので、終了時点の SIGHUP
を受け取らなくなる。SIGHUP
は受け付ける。なので、 disown
を用いたほうがよさそうな気がするが、
不慮の事故で SIGHUP
が送られても終了しないという意味では nohup
のほうがよさそうだ。
-l
オプション利用できるシグナルの一覧を表示するコマンドだ。実際に見てみよう。
$ kill -l
やってみると
$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
結構多い。
このようにたくさんのシグナルが利用できることがわかる。 それぞれのシグナルIDもわかるはずだ。 全部解説しても意味があるとも思えないので、使いやすいものだけご紹介しよう。
シグナル名 シグナルID 動作 HUP 1 ハングアップ(端末が制御不能もしくは切断による終了) INT 2 キーボードからの割り込み(Ctrl+Cと同じ) KILL 9 強制終了(デフォルトよりも強制的に修正する) TERM 15 終了(デフォルトの設定だ) CONT 18 停止しているプロセスを再開 STOP 19 一時停止
ということなので、
$ kill -SIGTERM PID
$ kill -SIGHUP PID
$ kill -SIGKILL PID
辺りを利用することになるのだろう。これを上から順番に試して消せるものを探すというのが良さそうだ。
ただし -SIGKILL
は本当に強制終了なのでなるべくは避けたい。
psコマンドとは
実行中のプロセスを表示するコマンドです。表示されるプロセスの要素を下に記します。
要素 意味 F プロセスの状態 USER ユーザID PID プロセスID %CPU CPU使用率 %MEM 実メモリ使用量 VSZ 仮想メモリの使用サイズ(キロバイト表示) RSS 物理メモリの使用サイズ(キロバイト表示) TTY 使用端末 STAT プロセスのステータス PRI プロセスの優先度 PPID 親プロセスのPID NI 優先度を示すNICE値 SZ プロセスが確保しているメモリサイズ WCHAN スリープ時のカーネル関数名 F(プロセスの状態)
Fは16進数で表記される。
状態表記 意味 00 終了 01 システム上の常駐プロセス 02 親プロセスからトレースされている 04 親プロセスからトレースされている状態で停止している 08 起動不可能 10 プロセスがメモリ上にありイベント終了までロックされている 20 スワップ不可能 STAT(プロセスステータス)
ステータス表記 意味 S 割り込み可能なスリープ状態 s セッションリーダ D 割り込み不可能なスリープ状態 R 実行可能状態(待ち状態) O 実行中 I プロセス生成中 Z 親プロセスとの関係が切れた状態(ゾンビプロセス) N 優先度低い > 優先度高い + フォアグラウンドのプロセスグループに入っている T 停止中
ps ax
を実行してみる
PID TTY STAT TIME COMMAND
....
6227 ? S 0:00 sudo nohup ./start_hls.sh
6228 ? S 0:00 /bin/sh ./start_hls.sh
6229 ? Sl 4000:53 avconv -f video4linux2 -input_format mjpeg -video_size 1 ...
...
6227-9
が HLS 配信を nohup
で動作したプロセスであることが確認できる。このプロセスは
$ sudo nohup ./start_hls.sh
で生成されたもの。