いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

nohupコマンド (端末セッションから切断されてもプログラムを実行し続ける)

概要

以下、自分用のメモです。使いたい時によく忘れるのでここにメモメモ。。。

Linux上でなんらかのコマンドをバックグラウンドで動かしていて、終わるのを待つ前に間違ってセッションを切断(つまりexitとかlogout)しちゃったことってありませんか?私はたまにあったりします。そういうときに、セッションが切断されていても裏で動いていてほしいときがあります。

そのときに知ってると便利なのが、nohup コマンドさんです。

どちらも、端末セッションが切断されてもプログラムを実行し続けるようにしてくれます。

ためしてみる

前提として、bashを使っている場合、シェルオプションの huponexit というものが off で設定されている可能性があります。

このシェルオプションは名前の通りで、exit時に今動いているシェル経由のプロセスに対して HUP (Hang UP) シグナル (SIGHUP) を送るかどうかの設定です。

これが、off になっていると、nohup コマンドを使うまでもなく、exit してもプロセスは動き続けてくれます。

なので、先にこのシェルオプションの設定を確認しましょう。

私の環境 (Chromebook 上の Debian GNU/Linux 12) では、

$ shopt huponexit
huponexit       off

とオフになっていました。なので、これをオンにしておかないと nohup コマンドさんの効能が分かりません。

なので、on にします。

$ shopt -s huponexit
$ shopt huponexit
huponexit       on

これで、exit 時に HUP シグナルが飛ぶようになりました。

まずは、nohup 無しの場合にどのようになるか見てみます。

$ sleep 1000 &
[1] 1672

$ ps -p 1672
  PID TTY          TIME CMD
 1672 pts/1    00:00:00 sleep

裏で動いているのを確認して、このセッションを exit します。

$ exit

んで、別のターミナルを起動して確認してみます。

$ ps -p 1672
  PID TTY          TIME CMD

いませんね。huponexit が作動して exit 時に PID 1672 のプロセスにはHUPシグナルが送られていてKILLされています。

nohup コマンドを使ってみる

んで、お目当ての nohup コマンドを使ってみます。

やり方はさっきと同じですが、プロセスを起動するときに先頭に nohup を付与します。

$ nohup sleep 1000 &
[1] 1883
nohup: 入力を無視し、出力を 'nohup.out' に追記します

nohupコマンドからの通知で、出力が nohup.out に出力されていくよって教えてくれてます。

$ ls nohup*
nohup.out

確かにありますね。

あとは同じように プロセス がいるのを確認して exit して、別のターミナルで見てみましょう。

$ ps -p 1883
  PID TTY          TIME CMD
 1883 pts/1    00:00:00 sleep

$ exit

別のターミナルで見ると

$ ps -p 1883
  PID TTY          TIME CMD
 1883 ?        00:00:00 sleep

プロセスを起動した端末セッションは切断されているのに、nohup 付きで起動したプロセスはHUPされずに動き続けています。

基本、bashでは huponexit がデフォルトでoffになっているので、あまり使うことはないかもしれませんが知識として知っておくと便利かもしれません。

参考情報


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。