page_adsence

2014年12月26日金曜日

ログアウト後もコマンドを実行し続ける。または今動いているコマンドを後からログアウトしても実行し続けるようにする。

ログアウトした後も継続してコマンドを実行し続けるためには、nohupコマンドを使う必要がある。
通常はログアウトしたタイミングでkillされてしまうのだが、そのシグナルを無視するようになります。
また、標準出力や標準エラーはファイルに出力されるようになります。

■使ってみる
$ nohup ./test.sh &

test.shをバックグラウンドで実行する。
「test.sh」の標準出力、標準エラー出力に送られたデータはプログラムを実行したディレクトリに「nohup.out」というファイル名で保存される。
もしプログラムを実行したディレクトリに書き込み権限が無ければ「$HOME/nohup.out」に保存される。

■標準出力先を指定する
$ nohup ./test.sh > stdout.log &

「test.sh」の標準出力が「stdout.log」になる。標準エラー出力は「nohup.out」で保存先は先ほどと同様にプログラムを実行したディレクトリか、$HOME配下に作られる。

■標準エラー出力先を指定する
$ nohup ./test.sh > stdout.log 2 > stderr.log &

「test.sh」の標準出力が「stdout.log」になる。標準エラー出力は「stderr.log」です。


nohupコマンドで実行する前に普通にコマンドを打ってしまった場合、 または思った以上に時間が掛かってしまってもう帰らないと行けなくなってしまった時の対応方法。


1.処理中にCtrl + zで一旦閉じる

2.バックグラウンドにする
$ bg

3.SIGHUBが送られないようにする
$ disown %1 ← %の後の数値はjob番号。jobsで調べた時に出てくる番号を入れる。

ここまででログアウトしても問題なくなる。
しかし標準出力や標準エラーが取れない。
それを取るためにする方法が以下の方法

4.プロセス番号を調べる
$ ps aux
user   5791  3.6  0.1 194640 32136 ?        S    15:36   0:21 ./test.sh
上記の場合だとプロセス番号は5791。

5.標準出力や標準エラーを保存するためのファイルを用意する。
$ touch stdout
$ touch stderr
※カレントディレクトリに作成

6.gdbで繋ぐ
$ gdb -p 5791

(gdb) p dup2(open("stdout",1),1) ← カレントディレクトリにあるstdoutというファイルに標準出力を入れる

(gdb) p dup2(open("stderr",1),2) ← カレントディレクトリにあるstdoutというファイルに標準エラーを入れる

(gdb) detach

(gdb) quit

以上で完了。
後は実際にファイルに書き込まれているかを確認する。
$ tail -f stdout
$ tail -f stderr