シェルを終了してもコマンドを継続する方法

UNIX

スクリプトなどを作ってコマンドラインから実行したのは良いけど、ログアウトしなければいけない状況になることは良くあります。例えば、リモート端末からサーバにログインしていて、スクリプトを実行したけど時間がかかる処理で終わらず、端末を落とせなくなるとかです。

バックグラウンドにしてもシェルが終了すると死ぬ

シェルから実行したコマンドは、ジョブとして管理されていてシェルを終了してしまうとSIGHUPシグナルが送られて死んでしまいます。これはバックグラウンドプロセスにしても同じです。

なので単に後ろに&をつけて実行したり、Ctrl-Zで停止して bg でバックグラウンドにしてもログアウトするとそのプロセスは死んでしまいます。

SIGHUPシグナルを受けなくする

方法は2つあって、一つ目はSIGHUPシグナルを受けなくさせることです。シェルが終了するときに登録されているジョブに対してSIGHUPシグナルを送るのですが、これを無効化させることができます。

このやり方は実行時にnohupコマンド経由で実行することです。

# nohup foo.sh > /tmp/out.log 2>&1 &

nohup は標準出力をリダイレクトしていないと実行したディレクトリにnohup.outとして保存してしまうので、ごみを置きたくないディレクトリから実行する場合は注意です。

ジョブ管理から外す

もう一つの方法は、disownを使ってジョブの管理から外してしまうことで、これは実行後に行います。

disown はjobsの番号を指定して特定のジョブに対して管理から外すことができます。

# bar.sh
^Z
[1]+  Stopped                 bar.sh
# bg
[1]+ bar.sh &
# jobs
[1]+  Running                 bar.sh &
# disown -a

一番良くあるケースは、コマンドを実行したときは席を離れる前に終わる予定だったけど、終わらないからCtrl-Zで止めて、bgでバックグランドにして disown する場合ですね。

コメント