概要

SSH等でサーバにログインして何かのプログラムを実行しているときに、そのプログラムのタスクがログアウトした時に終了し、最後まで実行されていないということがあります。
これは、実行終了までに時間がかかるようなプログラムを実行している時に、実体験としてよくあります。
ログアウトの原因としては、急にネットワークが不安定になってログアウトされてしまう場合もあれば、バックグラウンドでプログラムを実行しているから大丈夫だろうと思って自らログアウトするという場合もあります。

今回は、このようなログアウトしてもプログラムのタスクが実行されるようにする方法を紹介します。

環境

  • Ubuntu 19.04

失敗例

最初に、うまくいきそうでいかない失敗例を紹介します。

私が試して失敗した例として、バックグラウンドの実行があります。

$ コマンド &

バックグラウンドでの実行は、ターミナルでの実行の際にアンパサンド(&)をつけて実行することでできます。
しかし、これではログアウトの際にバックグラウンドの処理も一緒に終了するため、失敗します。

原因

そもそものログアウト時にタスクが終了する原因としては、タスクのプロセスがログインの際に起動するシェルのプロセスに紐づいており、ログアウト時には、シェルのプロセスが終了するのですが、この時シェルのプロセスに紐づけられたプログラムのタスクのプロセスも一緒に終了してしまうということが原因です。

これの解決方法として、私は2つの方法を説明します。

nohupを使った解決方法

最初の解決方法として、nohupコマンドを使う方法を紹介します。

次のように、プログラムの実行のコマンドの前にnohupと書きます。

$ nohup コマンド &

nohupは、シェルの終了時などに発火するHUPシグナルを無視するようにするコマンドです。
そのため、nohupを使用すればシェルの終了時にプログラムが終了せずに済みます。

もし、コマンドの実行中に、「思ったより実行に時間がかかるので後からnohupを使ってログアウト後も実行するようにしておけばよかった」となる場合には「Ctrl+z」で一度ジョブを停止してから次のようにします。

$ bg 1
$ disown -h 1

disownは、実行中のジョブに対してシェルの終了時にHUPシグナルを無視するために使用しています。

screenなどを使った解決方法

もうひとつの方法に、screenなどの仮装ターミナル管理ソフトを使う方法です。
代表的なものには、screenやtmuxがあります。
これを使うことで、仮装的なシェルをつくることができ、このシェルはログアウト後も残ります。
そのため、これらを使ってログアウト後もタスクを実行させることが可能です。

今回はscreenを例にします。

まず、screenがインストールされていない環境もあるため、次のコマンド等でインストールしておきましょう。

$ sudo apt install -y screen

screenの使い方は少し複雑なため、詳細な使い方の説明は他のサイトに譲り、ここでは簡単な使い方を紹介します。
基本的に次のように使います。

$ screen コマンド &

これでログアウト後もタスクを実行させることができるようになりました。

さいごに

覚えてしまえばかなり簡単にできると思います。

同じ悩みを持つ人の参考になれば幸いです。