nohup/disown/screen - ターミナル切断後もプロセスを残す

nohup/disown/screen - ターミナル切断後もプロセスを残す

この記事で解決できること

  • SSH 切断・ターミナル終了後もコマンドを 継続させる 3 つの方法 が分かる
  • nohup / disown / screen正しい使い分け基準 が身につく
  • 「うっかり nohup を付け忘れた」ときの 事後対応 ができる

結論(実務の型)

状況 手段
最初から継続させる nohup cmd &
実行後に切り離す disown %1
セッションを丸ごと保持 screen または tmux

SIGHUP とは何か?

プロセスがターミナル切断後に死ぬ直接の原因は、シェルが配下のプロセスに送る SIGHUP(Signal 1: Hangup) にある。

ターミナルを閉じる、SSH 接続を切断する、いずれの場合もシェルは終了前に自分の管理するプロセスグループへ SIGHUP を送信する。デフォルトのシグナルハンドラは終了なので、バックグラウンドで走っているコマンドも道連れになる。

$ sleep 300 &
[1] 12345
$ exit   # シェル終了 → sleep に SIGHUP → 12345 が終了

以下で紹介する 3 つの手段は、それぞれ異なるレイヤーでこの SIGHUP 配送を遮断する。

nohup — 実行前に使う

nohup("no hangup" の略)は、コマンドを SIGHUP を無視する状態 で起動する。

$ nohup long-job.sh &
  • & は任意だが、バックグラウンド実行とセットにするのが慣例
  • STDOUT / STDERR は nohup.out(カレントディレクトリ)へ自動リダイレクト
  • ログファイルを明示する場合:
$ nohup ./deploy.sh > /var/log/deploy.log 2>&1 &

出力が不要なら /dev/null へ捨てる。nohup.out が無制限に肥大化するのを防げる。

$ nohup ./job.sh > /dev/null 2>&1 &

nohup は SIGHUP をブロックするだけであり、プロセスをデーモン化するわけではない。シェル終了後もプロセスは生存するが、親プロセスは init(PID 1)に付け替わる。

disown — 実行後に使う

disown は、すでに走っているジョブを シェルの job table から削除し、SIGHUP を配送しないようにする。nohup を付け忘れて実行してしまったときの事後対応に使う。

# 実行中のジョブを確認
$ jobs
[1]+  Running    long-job.sh &

# ジョブ番号を指定して切り離す
$ disown %1

# すべてのジョブを切り離す
$ disown -a

disown -h(SIGHUP だけ除外)

job table から完全に消さず、SIGHUP の配送だけを止める。jobs での確認は引き続き可能。

$ disown -h %1

nohup を付け忘れたときの手順

# 1. フォアグラウンドで動いているなら Ctrl+Z で一時停止 → bg で再開
$ Ctrl+Z
[1]+  Stopped    ./deploy.sh
$ bg %1
[1]+ ./deploy.sh &

# 2. disown で SIGHUP を切る
$ disown %1

# 3. ターミナルを閉じても OK

screen — セッションを永続化する

screen はターミナルセッション全体を仮想化する ターミナルマルチプレクサ。核心機能は デタッチ→再接続 で、別端末や別 SSH からセッションへ戻れる。

# 名前付きセッションを作成して接続
$ screen -S mysession

# セッション内で作業する
# (Ctrl+A D でデタッチ — screen は裏で生き続ける)

# 別の端末 / SSH から再接続
$ screen -r mysession

# セッション一覧を確認
$ screen -ls

よく使う screen キーバインド

操作 キー
デタッチ Ctrl+A D
ウィンドウ作成 Ctrl+A C
次のウィンドウ Ctrl+A N
前のウィンドウ Ctrl+A P
セッション終了 最後のウィンドウで exit

screen vs tmux

機能・設定の柔軟性では tmux が優れる。サーバに tmux が入っていれば積極的に使うべき。詳細は tmux 入門 を参照。サーバ環境で tmux が使えない、あるいはシンプルさを優先するなら screen で十分。

3 つの使い分けまとめ

手段 タイミング 特徴
nohup cmd & 実行前 シンプル・標準搭載・ログが nohup.out に残る
disown 実行後 付け忘れ対策・ログリダイレクトは自分で管理
screen / tmux どちらでも デタッチ・再接続・複数ウィンドウ管理が可能

避けるべきこと

  • nohup なしのバックグラウンドジョブのままターミナルを閉じる → SIGHUP で強制終了
  • screen セッション内で Ctrl+D を連打して「閉じた気」になる(実際はセッション終了)→ デタッチは Ctrl+A D
  • ログ出力先を指定せず nohup.out を溜め続ける → ディスク消費に注意

次に読む