Linux入門:コマンド操作のきほん

nohupでログアウト後も実行する

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

nohupでログアウト後も実行する とは

nohupコマンドで、ログアウト後もプログラムを実行し続ける方法を学びます。本レッスンでは、nohupでログアウト後も実行する の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

なぜ重要か

SSH でサーバーに入って長時間のバッチを流す、機械学習の学習を回す、データのバルクロードをかける、こうしたシーンで「Wi-Fi が切れたら処理も止まってしまった」では困ります。SSH の接続が切れた時、シェルからジョブに SIGHUP (hangup) が送られて、子プロセスがまとめて終了するのが Unix の伝統的な挙動だからです。

この問題を解決するのが nohup と、後で詳しく扱う screen / tmux といった多重端末ツールです。本レッスンでは概念と典型的なコマンドを整理します。本コースの実行環境 (Cloud Functions) では SSH や永続セッションを再現できないため、概念中心で進めます。

解きたい課題

diagram (will load when visible)

上図のように、SSH が切れると親プロセス chain を通じて SIGHUP が末端のジョブまで伝わります。nohup はこのシグナルを無視させるラッパーです。

nohup の基本

ターミナル

nohup コマンド [引数] &

nohup は次の 3 つを同時にやってくれます。

  • 起動するプロセスに SIGHUP を無視させる
  • 標準出力を nohup.out (またはリダイレクト先) に書き出す
  • 標準入力を /dev/null から取る (対話入力なしでも進む)

ターミナル

nohup ./long_job.sh > job.log 2>&1 & exit

このように起動してから SSH を抜けても、long_job.sh は走り続け、出力は job.log に溜まり続けます。

ログ出力先と権限

nohup コマンド & のように出力先を指定しないと、カレントディレクトリの nohup.out に書き込まれます。書き込み権限がない場合は $HOME/nohup.out にフォールバックします。意図しない場所に巨大ログが残らないよう、明示的にリダイレクトしておくのが安全です。

ターミナル

nohup ./batch.py > /var/log/batch/`date +%Y%m%d`.log 2>&1 &

本番サーバーで nohup ./script.sh & をうっかり実行すると、後で nohup.out を消そうとして既存ファイルとぶつかることがあります。最初から > で日付付きのログ名にしておくと、運用がきれいに保てます。

disown との違い

似た用途のコマンドに disown があります。

ターミナル

./long_job.sh & disown %1

disown は既に起動済みのジョブをシェルのジョブテーブルから外し、シェル終了時に SIGHUP を送らないようにします。nohup は起動時に被せるラッパー、disown は起動後に切り離すコマンド、という違いです。両者を覚えておくと「起動した後で気付いた」「最初から準備していた」のどちらにも対応できます。

道具タイミング標準出力の扱い
nohup起動時自動的にファイル化
disown起動後自分でリダイレクト要
&起動時端末にそのまま流れる

screen と tmux: 多重端末

nohup は便利ですが、後から「進捗を覗きたい」「中断して別のコマンドを挟みたい」と思っても、端末の中に入り直すことはできません。そこで使うのが screentmux のような多重端末ツールです。

ターミナル

tmux new -s deploy # 中で long_job.sh などを実行 # Ctrl+b d で デタッチ exit # SSH を抜ける # 後日 tmux attach -t deploy # 同じセッションに戻れる

仮想的な端末セッションを作って、好きなタイミングでアタッチ・デタッチできるため、長時間のデプロイ作業や検証作業との相性が抜群です。screen も思想は同じで、伝統的に使われてきました。

本格的な運用では tmuxscreen を覚えておくと圧倒的に楽です。コマンド体系は tmux の方がモダンで、リサイズ、ペイン分割、コピーモードなどが扱いやすい構造になっています。

systemd で常駐させる

本来「常時起動しておくべきプロセス」は、nohup のような単発の仕組みではなく systemd のサービスとして登録するのが推奨です。たとえば自作の Python アプリを常駐させる場合は次のような unit ファイルを書きます。

ini

[Unit] Description=My App After=network.target [Service] ExecStart=/usr/bin/python3 /opt/myapp/main.py Restart=on-failure User=myapp [Install] WantedBy=multi-user.target

そのうえで systemctl enable --now myapp.service で常駐化します。これなら再起動後も自動で立ち上がり、終了コードに応じた再起動も任せられます。nohup は「一時的にとりあえず流したい」ときの相棒、systemd は「正式に常駐させたい」ときの相棒、と棲み分けると整理しやすいです。

環境別のおすすめ

シーン推奨
5 分ほどの一括処理& だけで十分
数時間の単発バッチ、SSH 切断耐性が欲しいnohup または disown
複数の窓を行き来したい、進捗を覗きたいtmux (もしくは screen)
永続化・再起動耐性が必要なサービスsystemd で unit を作る

演習について

Cloud Functions サンドボックスでは SSH 切断や永続セッションを再現できないため、本レッスンの演習は概念整理に重きを置き、nohupdisown の挙動はローカル機で必ず一度試すことを推奨します。手元の Linux / macOS / WSL で nohup sleep 30 & exit のあとに別ターミナルで ps -ef | grep sleep を見ると、SSH 切断耐性を体感できます。

まとめ

  • SSH 切断時に親シェルから子へ SIGHUP が伝わってジョブが落ちることがある
  • nohup は SIGHUP を無視するラッパーで、& とセットで使う
  • 既に起動済みのジョブには disown で同じ効果を得られる
  • 長時間作業には tmux などの多重端末でセッションをアタッチ可能にしておく
  • 正式な常駐サービスは systemd でユニットを書いて再起動耐性まで持たせる

次のレッスン

次は プロセス管理チェック で、nohupコマンドで、ログアウト後もプログラムを実行し続ける方法を学びます を学びます。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. nohup と多重端末 の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. nohup と多重端末 とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

参考リンク