SSH切断と同時にコマンドが強制終了してしまうのは、端末を閉じたときにHUPシグナル(ハングアップシグナル)がプロセスに送られるためです。
この記事では、
nohup コマンドの使い方を解説します。SSHが切断されても処理を継続させる基本手順から、バックグラウンド実行の組み合わせ、出力ログの管理まで、実務で即使える内容を網羅します。この記事のポイント
・nohup コマンドで SSH 切断後もプロセスを継続実行できる
・nohup コマンド & でバックグラウンド実行と組み合わせるのが基本形
・出力は nohup.out に保存され、リダイレクトで任意ファイルに変更できる
・screen/tmux との違いと使い分けを押さえておくと現場で迷わない
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜ SSH 切断でプロセスが終了するのか
SSH でサーバーにログインして何らかのコマンドを実行しているとき、端末(ターミナル)を閉じたり、ネットワークが切れたりすると、実行中のコマンドが強制終了することがあります。この仕組みを理解するには「シグナル」の概念が必要です。Linux では、端末(疑似端末)が閉じられると、そのセッションで起動されたプロセスグループ全体に SIGHUP(シグナル番号 1) が送信されます。ほとんどのプロセスは SIGHUP を受け取ると終了します。
# SIGHUP の確認(シグナル一覧) $ kill -l | head -5 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP # 1 が SIGHUP
nohup コマンドは「no hang up」の略で、このSIGHUPを無視した状態でコマンドを起動します。つまり、SSH が切れても起動したプロセスは HUP シグナルを受け取らないため、処理を継続できます。nohup コマンドの基本的な使い方
1. 基本構文とシンプルな実行例
nohup の基本的な書き方は非常にシンプルです。実行したいコマンドの前に nohup を付けるだけです。# 書式 nohup コマンド [引数] # シンプルな例:Pythonスクリプトをnohupで実行 $ nohup python3 batch_process.py nohup: ignoring input and appending output to 'nohup.out'
2. バックグラウンド実行との組み合わせ(最頻出パターン)
実務ではnohup と &(バックグラウンド実行)を組み合わせるのが基本形です。# nohup + バックグラウンド実行(実務での基本形) $ nohup python3 batch_process.py & [1] 12345 nohup: ignoring input and appending output to 'nohup.out' # PID(プロセスID)が表示される → 12345 # バックグランドに回ったので端末はすぐに使える
[1] 12345 の数字がジョブ番号とプロセスID(PID)です。この PID を使えば、後からプロセスの状態確認や強制終了ができます。SSH を切断して再ログインした後も、プロセスが動いているかどうかは以下で確認できます。
# 再ログイン後のプロセス確認 $ ps aux | grep batch_process.py | grep -v grep tomohiro 12345 2.3 0.5 145200 21344 ? S 10:32 0:15 python3 batch_process.py # ? が tty 列 → 端末から切り離されていることを示す
? になっているのは、このプロセスが制御端末を持っていないことを示します。SSH ログアウト後も安全に動作している証拠です。3. 出力先(nohup.out)の確認
nohup で実行したコマンドの標準出力と標準エラー出力は、デフォルトでカレントディレクトリの nohup.out に追記されます。# nohup.out の確認 $ tail -f nohup.out [2026-04-25 10:35:01] Processing record 1001/5000... [2026-04-25 10:35:03] Processing record 1002/5000... [2026-04-25 10:35:05] Processing record 1003/5000...
tail -f でリアルタイムに出力を追跡できます。バッチ処理の進捗確認に便利です。出力先のカスタマイズ
1. 出力を任意のファイルにリダイレクトする
デフォルトのnohup.out では管理が煩雑になります。実務では出力先を明示的に指定します。# 標準出力を指定ファイルに保存 $ nohup python3 batch_process.py > /var/log/batch_process.log 2>&1 & # 解説: # > /var/log/batch_process.log ... 標準出力をファイルへ # 2>&1 ... 標準エラーを標準出力に統合 # & ... バックグラウンド実行
2>&1 を付けることで、エラー出力も同じファイルにまとめて記録されます。トラブル発生時に原因を追跡しやすくなるため、本番環境では必ずこの形式を使います。2. 標準出力と標準エラーを別ファイルに分ける
正常出力とエラーを分けて記録したい場合は、それぞれ別ファイルに向けます。# 標準出力とエラーを別ファイルに保存 $ nohup python3 batch_process.py \ > /var/log/batch_stdout.log \ 2> /var/log/batch_stderr.log & # 確認 $ ls -la /var/log/batch_*.log -rw-r--r-- 1 tomohiro tomohiro 12480 Apr 25 10:40 /var/log/batch_stderr.log -rw-r--r-- 1 tomohiro tomohiro 94320 Apr 25 10:40 /var/log/batch_stdout.log
3. 出力を破棄する(/dev/null へ)
ログが不要な場合や、出力が大量すぎてディスクを圧迫する恐れがある場合は、/dev/null に捨てます。# 出力を全て捨てる $ nohup ./cleanup_script.sh > /dev/null 2>&1 &
実行中プロセスの管理
1. PID を使った状態確認
nohup で起動したプロセスの PID は、起動時に表示されます。再ログイン後も ps や pgrep で確認できます。# プロセス名で検索 $ pgrep -f batch_process.py 12345 # 詳細情報を確認 $ ps -p 12345 -o pid,ppid,user,stat,etime,cmd PID PPID USER STAT ELAPSED CMD 12345 1 tomohiro S 00:15:42 python3 batch_process.py # PPID=1 (init/systemd) → 端末から切り離されている証拠
PPID(親プロセスID)が 1(systemd または init)になっていれば、元の SSH セッションから独立して動作していることを意味します。2. プロセスの停止(kill コマンド)
nohup で起動したプロセスを停止したい場合は、PID を指定して kill コマンドを使います。# 正常終了を試みる(SIGTERM) $ kill 12345 # 強制終了(プロセスが応答しない場合) $ kill -9 12345 # プロセス名で一括停止 $ pkill -f batch_process.py
kill 12345(SIGTERM)で正常終了を試みて、応答がない場合のみ kill -9(SIGKILL)を使います。SIGKILL はプロセスがシグナルをキャッチする機会を与えないため、ファイルが中途半端な状態で残るリスクがあります。
3. PID ファイルを使った管理
スクリプトを定期的に起動する場合や、PID を後から参照したい場合は、起動時に PID をファイルに保存しておくと便利です。# PID をファイルに保存しながらバックグラウンド実行 $ nohup python3 batch_process.py > /var/log/batch.log 2>&1 & $ echo $! > /var/run/batch_process.pid # $! は直前にバックグラウンドで起動したプロセスの PID # 後から PID を取得して操作 $ cat /var/run/batch_process.pid 12345 $ kill $(cat /var/run/batch_process.pid)
$! は bash のシェル変数で、直前にバックグラウンド実行したプロセスの PID を保持しています。この仕組みを活用すると、シェルスクリプトでのプロセス管理が格段に楽になります。nohup と screen/tmux の使い分け
SSH 切断後も処理を継続させる手段として、nohup のほかに screen や tmux があります。それぞれの特徴を把握して使い分けることが実務では重要です。| ツール | 再アタッチ(出力を後から見る) | インタラクティブ操作 | シェルスクリプトとの相性 |
|---|---|---|---|
| nohup | ログファイル参照のみ | 不可 | 優(シンプルに組み込める) |
| screen | セッションに再アタッチ可能 | 可 | 良(手動操作が前提) |
| tmux | セッションに再アタッチ可能 | 可 | 良(ペイン分割も可) |
・nohup:「起動したら後は任せる」バッチ処理向き。対話操作が不要な場面に最適
・screen/tmux:「後から途中経過を確認したい」「対話が必要」な作業向き
例えば、深夜バッチやデータ移行スクリプトなら
nohup で十分です。一方、インストール作業の途中で確認が必要だったり、ウィザード形式の設定画面があったりする場合は tmux が適しています。シェルスクリプトでの nohup 活用
1. スクリプト内で nohup を使う
複数のバックグラウンドジョブを管理するシェルスクリプトでもnohup は有効です。#!/bin/bash # run_batch.sh - 複数バッチをnohupで並列起動するスクリプト LOG_DIR=/var/log/batch mkdir -p "$LOG_DIR" echo "バッチ処理を開始します..." nohup python3 /opt/batch/import_users.py \ > "$LOG_DIR/import_users.log" 2>&1 & IMPORT_PID=$! nohup python3 /opt/batch/send_reports.py \ > "$LOG_DIR/send_reports.log" 2>&1 & REPORT_PID=$! echo "import_users PID: $IMPORT_PID" echo "send_reports PID: $REPORT_PID" echo "ログ確認: tail -f $LOG_DIR/*.log"
2. 完了を待機して結果を確認する
バックグラウンドで起動したジョブの完了を待つにはwait コマンドが便利です。#!/bin/bash # 2つのジョブを並列実行して、両方完了を待つ nohup python3 job_a.py > /var/log/job_a.log 2>&1 & PID_A=$! nohup python3 job_b.py > /var/log/job_b.log 2>&1 & PID_B=$! # 両方のジョブが完了するまで待機 wait $PID_A $PID_B echo "全ジョブ完了。ログを確認してください。" echo " /var/log/job_a.log" echo " /var/log/job_b.log"
wait コマンドを使うと、バックグラウンドジョブの完了を正確に検知できます。並列処理のシェルスクリプトでは必須のテクニックです。トラブルシュート・よくあるミス
「nohup: ignoring input」の意味
nohup 起動直後に表示されるメッセージですが、エラーではありません。$ nohup python3 batch_process.py & [1] 12345 nohup: ignoring input and appending output to 'nohup.out'
nohup.out が肥大化する問題
デフォルトではnohup.out に追記され続けるため、長時間稼働するプロセスではファイルサイズが膨大になる場合があります。# 問題:nohup.out が巨大になっている $ ls -lh nohup.out -rw-rw-r-- 1 tomohiro tomohiro 2.3G Apr 25 10:00 nohup.out # 対策1:最初から出力先を指定する $ nohup ./long_running.sh > /var/log/long_running.log 2>&1 & # 対策2:/dev/null に捨てる(ログ不要の場合) $ nohup ./long_running.sh > /dev/null 2>&1 &
プロセスが起動直後に終了してしまう
nohup ... & で起動したはずなのにプロセスがすぐに消えている場合の確認手順です。# 終了直後にプロセスを確認(終了コードを取得) $ nohup python3 batch_process.py > /var/log/batch.log 2>&1 & [1] 13210 $ wait $! [1]+ Exit 1 nohup python3 batch_process.py ... # Exit 1 はスクリプト内でエラーが発生したことを示す # ログを確認する $ tail -30 /var/log/batch.log Traceback (most recent call last): File "batch_process.py", line 5, in <module> import pandas as pd ModuleNotFoundError: No module named 'pandas'
nohup を使っているのに SSH 切断で終了してしまう
ごく稀に、nohup を付けているにもかかわらず SSH 切断後にプロセスが終了するケースがあります。原因として考えられるのは、起動したコマンドが内部で子プロセスを起動し、その子プロセスが SIGHUP を無視していない場合です。# 対策:trap でシグナルを明示的に無視する $ nohup bash -c 'trap "" HUP; ./complex_job.sh' > /var/log/job.log 2>&1 & # またはシグナルを無視する disown コマンドを使う $ ./complex_job.sh & $ disown %1
disown はバックグラウンドジョブをシェルのジョブリストから外すコマンドです。nohup と同様に SIGHUP を受け取らなくなります。起動後に「nohup を付けるのを忘れた」と気づいた際の救済手段として覚えておくと便利です。詳しいネットワーク診断手法については、Linux ポート確認の全コマンドも合わせて確認してください。
本記事のまとめ
| やりたいこと | コマンド |
|---|---|
| SSH切断後も処理を継続する | nohup コマンド & |
| 出力を任意のファイルに保存 | nohup コマンド > ファイル 2>&1 & |
| 出力を全て捨てる | nohup コマンド > /dev/null 2>&1 & |
| PID をファイルに保存 | nohup コマンド & echo $! > app.pid |
| プロセスを名前で検索 | pgrep -f スクリプト名 |
| プロセスを正常終了 | kill PID |
| プロセスを強制終了 | kill -9 PID |
| 起動後に切り離す(disown) | コマンド & disown %1 |
nohup はシンプルながら、サーバー運用の現場では非常に頻繁に使うコマンドです。特に深夜バッチ、データ移行、定期メンテナンススクリプトなど「起動したら翌朝確認すれば良い」処理に欠かせない存在です。バックグラウンド実行(
&)、出力リダイレクト(> ファイル 2>&1)、PID 管理の3点セットをセットで覚えておくと、どんな現場でも即戦力として活用できます。なお、長時間セッションを維持しながら作業したい場合は systemd-analyze で起動時間計測やシステム状態の確認も合わせて行うと、バッチ処理前後のシステム負荷を把握するうえで役立ちます。
よくある質問(FAQ)
Q. nohup で起動したプロセスはシステム再起動後も残りますか?
残りません。nohup はあくまで「SSH 切断(SIGHUP)を無視する」仕組みです。サーバー再起動後も処理を自動起動させたい場合は、systemd のサービスユニット(.service ファイル)を作成して systemctl enable で登録するのが正しい方法です。Q. & を付けない nohup とどう違いますか?
& を付けないと、コマンドはフォアグラウンドで実行されます。SSH 切断には耐えますが、端末を占有し続けます。次のコマンドを打てない状態になるため、nohup コマンド & の形で使うのが実務標準です。Q. nohup の出力がリアルタイムにファイルに書かれない場合は?
Python スクリプトなどはデフォルトで出力をバッファリングするため、nohup.out にすぐ反映されないことがあります。Python の場合は -u オプション(unbuffered)を付けることで解決できます。# Python のバッファリングを無効にする $ nohup python3 -u batch_process.py > /var/log/batch.log 2>&1 &
Q. nohup と disown の違いは何ですか?
nohup は「コマンドを起動するとき」に SIGHUP を無視する設定をします。一方、disown は「すでにバックグラウンドで動いているジョブ」をシェルのジョブリストから外す操作です。nohup を付け忘れた場合の救済手段として disown を使います。Q. cron から起動するスクリプトにも nohup は必要ですか?
cron から起動されるスクリプトには通常nohup は不要です。cron は端末セッションを持たず、最初から SIGHUP が送られない環境で動作します。ただし、cron のスクリプトがさらに長時間の子プロセスを起動する場合は、シグナル管理の観点から nohup を付けることがあります。cron の詳しい設定方法については、ntpd 時刻同期設定と合わせて確認すると、サーバー運用の定期処理全体を体系的に把握できます。
nohupで一歩進んだ。次はLinuxサーバー運用の全体像を体系的に押さえませんか?
バックグラウンド実行やプロセス管理を理解することは、Linuxサーバー運用の基礎です。断片的な知識だけでは、本番環境のトラブルで冷静に対応できません。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら
- 次のページへ:sarコマンドでシステムパフォーマンスを時系列で確認する方法|CPU・メモリ・ディスク統計の読み方と活用も
- 前のページへ:typeコマンドでシェル組み込みと外部コマンドを区別する方法|whichとの違いやalias確認も
- この記事の属するカテゴリ:Linuxtips・シェルスクリプトへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます