nohup コマンドの使い方|バックグラウンド実行・nohup.out制御とプロセス管理

コマンドリファレンス

SSHでリモートサーバーに接続して長時間かかるスクリプトやバッチ処理を実行中、ネットワークの切断やターミナルの誤終了によって処理が強制終了してしまった経験はないでしょうか。nohup(ノーハップ)コマンドを使えば、SSH接続を切断(ログアウト)した後もプロセスを中断させずにバックグラウンドで継続実行させることができます。

ただし、「nohup 単体ではバックグラウンド化しない」「& だけだと回線切断時に落ちる」「標準出力が nohup.out に溢れる」といった落とし穴も存在します。本記事では、実務で即コピペできる鉄板コマンド構文nohup.out のログ制御、実行中プロセスの確認(ps / pgrep)および安全な停止(kill / pkill)の手順まで網羅して解説します。

【最速コピペ】nohup の鉄板コマンド

# 1. ログをファイルに記録してバックグラウンド実行(標準出力・標準エラー出力を統合)
nohup ./long-task.sh > task.log 2>&1 &

# 2. ログが不要な場合(/dev/null に破棄し、nohup.out も生成させない)
nohup ./long-task.sh > /dev/null 2>&1 &

# 3. 再接続後にプロセスが動いているか確認
pgrep -a -f long-task.sh
ps aux | grep long-task.sh

# 4. 実行中のプロセスを停止
kill $(pgrep -f long-task.sh)
    1. 【最速コピペ】nohup の鉄板コマンド
  1. 即コピペで使える nohup 鉄板コマンド構文早見表
  2. nohup とは?仕組みと基本構文
    1. 構文
  3. 「nohup コマンド > 出力先 2>&1 &」の書き方を完全分解
    1. なぜ「2>&1」は「> output.log」の後ろに書くのか?
  4. nohup.out の仕組みとログの制御方法
    1. nohup.out が作成される場所のルール
    2. nohup.out を作成させない・肥大化させない方法
    3. 「nohup: ignoring input」メッセージを非表示にする方法
  5. 実行中のプロセス確認手順(ps / pgrep / jobs)
    1. 1. 起動直後の PID を取得・記録しておく(推奨)
    2. 2. 同一セッション内での確認:jobs コマンド
    3. 3. SSH再接続後・別端末からの確認:ps / pgrep コマンド
    4. 4. ログのリアルタイム追跡:tail -f
  6. プロセスの停止と強制終了(kill / pkill)
    1. 1. PID を指定して安全に停止(kill)
    2. 2. 終了しない場合の強制停止(kill -9)
    3. 3. プロセス名を指定して一括停止(pkill)
      1. 安全な停止のベストプラクティス
  7. 【実測検証】「&」だけ vs nohup vs disown vs setsid の切断耐性
    1. 検証結果の比較表
    2. なぜ「&」だけでも exit ログアウトなら生き残るのか?
    3. プロセスが SIGHUP を無視しているか確認する方法
  8. 実務で役立つ応用テクニックと注意点
    1. 1. Pythonスクリプト実行時は「python -u」を付ける
    2. 2. パイプライン全体を保護する場合は「bash -c」で包む
    3. 3. すでに起動してしまったプロセスを救済する(disown)
    4. 4. tmux / screen / systemd との使い分け
  9. トラブルシューティング(よくある疑問・FAQ)
    1. Q1. nohup を付けたのにSSHログアウト後にプロセスが停止していました
    2. Q2. nohup.out のログが肥大化してディスクを圧迫しています
    3. Q3. コマンドの起動自体に失敗したか確認するには?
  10. まとめ
  11. 関連記事

即コピペで使える nohup 鉄板コマンド構文早見表

実務でよく使われる nohup の代表的なユースケースと構文をまとめました。

用途・ユースケース コマンド構文 解説
標準出力・エラーをログ保存(上書き) nohup command > app.log 2>&1 & app.log に標準出力・エラー出力をまとめて保存しバックグラウンド実行
ログを追記保存 nohup command >> app.log 2>&1 & 既存ログを残したまま末尾に追記(定期バッチ向け)
ログ完全破棄(nohup.out 不要) nohup command > /dev/null 2>&1 & ディスク容量を消費せずに出力をすべて破棄
入力も完全遮断(警告メッセージなし) nohup command < /dev/null > app.log 2>&1 & nohup: ignoring input メッセージを出さずに完全デタッチ
Pythonスクリプトの即時ログ出力 nohup python -u app.py > app.log 2>&1 & -u で標準出力のバッファリングを無効化し、ログを即時反映
Node.js / アプリのバックグラウンド起動 nohup npm start > app.log 2>&1 & Node.js サーバー等を切断後も稼働継続
root権限が必要な処理 sudo nohup command > app.log 2>&1 & 管理者権限で実行(ログファイルの所有者は root になります)
パイプライン全体の保護 nohup bash -c 'cmd1 | cmd2' > app.log 2>&1 & パイプ後続コマンドも含めて切断耐性を持たせる

nohup とは?仕組みと基本構文

nohup(「no hang up」の略称、読み方:ノーハップ)は、Linux/Unix 環境で端末切断時に送信される SIGHUP(ハングアップシグナル・シグナル番号 1)を無視(ignore)してコマンドを実行するためのユーティリティです。

通常、SSH クライアントを終了したり回線が切断されたりすると、カーネルおよび親シェルからそのセッション配下のすべてのプロセスに対して SIGHUP が送信され、処理が道連れで終了(強制切断)します。nohup を前置して起動されたプロセスは SIGHUP を無視するため、親シェルや端末が消滅してもプロセスが孤立(init / systemd が親プロセス PID 1 として引き取り)した状態で実行を継続できます。

構文

nohup コマンド [引数...] [&]

nohup 単体には動作を変更する特別なオプションはなく、--help--version のみが用意されています。

重要:nohup は「バックグラウンド化」するコマンドではありません

nohup が行うのは「SIGHUPシグナルを無視させる」ことだけです。末尾に &(バックグラウンド実行)を付けずに nohup ./script.sh と実行すると、現在の端末のフォアグラウンドを占有したままになります。実務では必ず末尾に & を付けて実行してください。

「nohup コマンド > 出力先 2>&1 &」の書き方を完全分解

現場で最も使われる定型文 nohup command > output.log 2>&1 & の各パーツがどのような役割を果たしているかを分解して確認します。

nohup  command  > output.log  2>&1  &
  (1)     (2)        (3)       (4)  (5)
番号 パーツ 役割 詳細
(1) nohup SIGHUP シグナルを無視 SSH切断やターミナル終了時の道連れ終了を防止する
(2) command 実行対象のコマンド・スクリプト シェルスクリプト、Python、Node.js、DBバックアップなど
(3) > output.log 標準出力(fd 1)のリダイレクト 画面に出力される通常メッセージを output.log に書き込む(上書き)
(4) 2>&1 標準エラー出力(fd 2)の合流 標準エラー出力を標準出力(fd 1)と同じ書き込み先に統合する
(5) & バックグラウンド実行 シェルからプロセスをバックグラウンドに回し、即座にプロンプトを復帰させる

なぜ「2>&1」は「> output.log」の後ろに書くのか?

リダイレクトは左から右へ順番に解釈されます。

  • 正しい順序(> output.log 2>&1
    まず標準出力(1)が output.log を向きます。次に 2>&1 により、標準エラー(2)が「現在標準出力が向いている先(output.log)」に向けられます。結果として、両方が output.log に集約されます。
  • 誤った順序(2>&1 > output.log
    まず標準エラー(2)が「現在の標準出力の向き先(端末画面)」に向けられます。その後に標準出力(1)だけが output.log に変更されるため、エラーメッセージがファイルに記録されず画面に漏れてしまいます

nohup.out の仕組みとログの制御方法

リダイレクト先を自分で指定せずに nohup command & を実行すると、nohup は出力を自動的に nohup.out というファイルへリダイレクトします。

nohup.out が作成される場所のルール

  1. 第1候補:コマンドを実行したカレントディレクトリ./nohup.out
  2. 第2候補(フォールバック):カレントディレクトリに書き込み権限がない場合、実行ユーザーのホームディレクトリ $HOME/nohup.out に作成されます。

ホームディレクトリにも書き込み権限がない場合は起動エラー(Permission denied)となります。

nohup.out を作成させない・肥大化させない方法

nohup.out が意図せず肥大化してサーバーのディスク容量(ストレージ)を圧迫するトラブルは非常によくあります。以下の対策を使い分けましょう。

# 【対策1】出力先を明示的に指定する(nohup.out は生成されません)
nohup ./my_script.sh > /var/log/my_app/app.log 2>&1 &

# 【対策2】ログが一切不要な場合は /dev/null に破棄する
nohup ./my_script.sh > /dev/null 2>&1 &

# 【対策3】日付付きログファイルに分けて出力する
nohup ./my_script.sh > "backup_$(date +%Y%m%d_%H%M%S).log" 2>&1 &

「nohup: ignoring input」メッセージを非表示にする方法

nohup は標準入力が端末に接続されている場合、自動的に入力を切り離して nohup: ignoring input... という案内メッセージを出力します。このメッセージを完全に消したい場合は、標準入力にも < /dev/null を指定します。

nohup ./script.sh < /dev/null > app.log 2>&1 &

実行中のプロセス確認手順(ps / pgrep / jobs)

nohup でバックグラウンド起動した後は、プロセスが正しく稼働しているかを確認する必要があります。

1. 起動直後の PID を取得・記録しておく(推奨)

コマンドを実行した直後に、シェル変数 $!(直前にバックグラウンド実行されたプロセスのPID)をファイルに保存しておくと、後からの確認や停止が極めてスムーズになります。

nohup python -u batch.py > batch.log 2>&1 &
echo $! > /tmp/batch.pid

# 記録した PID で状態を確認
cat /tmp/batch.pid
# 出力例: 48210

2. 同一セッション内での確認:jobs コマンド

SSH接続を切断する前の同一ターミナルセッション内であれば、jobs コマンドで実行中のバックグラウンドジョブ一覧を確認できます。

jobs -l
# 出力例:
# [1]+ 48210 Running                 nohup python -u batch.py > batch.log 2>&1 &

※ 一度ログアウトして再接続した新しいシェルセッションでは、jobs の管理テーブルが引き継がれないため、後述の pspgrep を使用します。

3. SSH再接続後・別端末からの確認:ps / pgrep コマンド

SSHに再接続した後は、pgrepps コマンドでプロセスを検索します。

# pgrep でプロセス名・引数付きで検索
pgrep -a -f batch.py
# 出力例: 48210 python -u batch.py

# ps コマンドで詳細なCPU/メモリ使用率と起動状態を確認
ps aux | grep batch.py | grep -v grep

4. ログのリアルタイム追跡:tail -f

tail -f を使うことで、プロセスの出力ログをリアルタイムに監視できます。

tail -f batch.log

プロセスの停止と強制終了(kill / pkill)

nohup で起動したプロセスは SIGHUP(1)を無視するだけであり、通常の終了シグナル SIGTERM(15) や強制終了 SIGKILL(9) は正常に受け付けます。

1. PID を指定して安全に停止(kill)

まずは通常の終了シグナル(SIGTERM)を送信し、プロセス側に終了処理(ファイルの保存やDB接続のクローズ)を行わせます。

# 通常停止(SIGTERM)
kill 48210

# PIDファイルから停止する場合
kill $(cat /tmp/batch.pid)

2. 終了しない場合の強制停止(kill -9)

プロセスが応答しない場合やループに入って停止しない場合は、強制終了シグナル(SIGKILL)を送ります。

# 強制終了(SIGKILL)
kill -9 48210

3. プロセス名を指定して一括停止(pkill)

PIDを調べる手間を省きたい場合は、pkill を使ってコマンド名や引数でまとめて停止できます。

# batch.py に一致するプロセスを通常終了
pkill -f batch.py

# 止まらない場合は強制終了
pkill -9 -f batch.py

安全な停止のベストプラクティス

  1. まず kill <PID>(または pkill -f <name>)を実行する。
  2. kill -0 <PID>pgrep -f <name> でプロセスが終了したか確認する。
  3. 5〜10秒経過してもプロセスが残存している場合のみ kill -9 <PID> を使用する。

【実測検証】「&」だけ vs nohup vs disown vs setsid の切断耐性

& だけを付けたバックグラウンド実行と、nohupdisownsetsid は何が違うのか?」という疑問について、Ubuntu 24.04 LTS / Bash 5.2 環境で実際の切断挙動を実測検証しました。

検証結果の比較表

起動方法 突然の回線断・SSH強制切断 正常なログアウト(exit SIGHUPシグナルの無視 実行後の後付け適用
command & のみ 強制終了 ⭕ 生存(既定設定時) なし 不可
nohup command & 生存 生存 あり(無視) 不可(起動時のみ)
command &disown 生存 生存 なし(ジョブ表から除外) 可能(後付け可)
setsid command 生存 生存 なし(新セッション化) 不可(起動時のみ)

なぜ「&」だけでも exit ログアウトなら生き残るのか?

Bash には huponexit というシェルオプションが存在します。これが off(デフォルト)の場合、ユーザーが exit コマンドで正常にログアウトした際には Bash は配下のジョブに SIGHUP を送信しません。そのため、command & だけでもプロセスが残ります。

しかし、Wi-Fiの瞬断、PCのスリープ、SSHクライアントのクラッシュなど「予期せぬ切断」が発生した場合は、OSカーネルが制御端末の消滅を検知してセッション全体へ容赦なく SIGHUP を送信します。このとき nohup が付いていないプロセスは即座に道連れ終了してしまいます。これが実務で「必ず nohup を付けるべき」とされる最大の理由です。

プロセスが SIGHUP を無視しているか確認する方法

Linux では /proc/<PID>/status 内の SigIgn(無視しているシグナルの16進マスク)を見ることで、そのプロセスが本当に SIGHUP を無視しているかを客観的に確認できます。

# nohup ありで起動
nohup sleep 300 > /dev/null 2>&1 &
# [1] 50123

grep SigIgn /proc/50123/status
# SigIgn: 0000000000000001  ← 最下位ビットが 1(末尾が奇数)なら SIGHUP を無視している

実務で役立つ応用テクニックと注意点

1. Pythonスクリプト実行時は「python -u」を付ける

Python を nohup python script.py > script.log 2>&1 & で実行すると、標準出力が端末ではなくファイルに向けられたことで Python 側がバッファリングモードに入り、tail -f script.log を見てもログがリアルタイムに更新されない現象が発生します。

これを防ぐには、-u オプション(非バッファモード) を付与します。

nohup python -u script.py > script.log 2>&1 &

2. パイプライン全体を保護する場合は「bash -c」で包む

単に nohup cmd1 | cmd2 & と書くと、nohup は左側の cmd1 にしか適用されず、右側の cmd2 は SIGHUP を受けて終了してしまいます。

パイプライン全体を切断から保護するには、bash -c(または sh -c)で1つのコマンドとしてラップします。

nohup bash -c 'mysqldump -u root mydb | gzip > /backup/mydb.sql.gz' > dump.log 2>&1 &

3. すでに起動してしまったプロセスを救済する(disown)

nohup を付け忘れて command & で動かしてしまったが、今すぐログアウトしたい」という場合は、シェル組み込みコマンドの disown を使います。

# 1. 実行中のジョブ番号を確認
jobs
# [1]+ Running ./long-task.sh &

# 2. ジョブをシェルの管理対象から外す
disown %1

disown で切断耐性は付きますが、すでに出力先が端末に向いている場合、切断後の標準出力は失われます。重要なログを残したい場合は最初から nohup command > log 2>&1 & で起動してください。

4. tmux / screen / systemd との使い分け

ツール / 手段 最適なユースケース 特徴・メリット
nohup 単発のバッチ処理、DB移行、スクリプト実行 追加インストール不要、1行で手軽に即実行可能
tmux / screen 対話的操作が必要な作業、進捗画面を見ながらの作業 ログアウト後も同じ端末画面(セッション)に再接続(アタッチ)して作業再開できる
systemd Webサーバー、常駐デーモン、自動起動が必要なサービス OS再起動時の自動起動、異常終了時の自動再起動(Restart=always)など本格的な管理が可能

トラブルシューティング(よくある疑問・FAQ)

Q1. nohup を付けたのにSSHログアウト後にプロセスが停止していました

以下の原因を順に確認してください:

  1. systemd-logind の KillUserProcesses 設定
    一部のディストリビューション(RHEL系等)では KillUserProcesses=yes に設定されており、ログアウト時にユーザープロセスが全停止させられます。loginctl show-session | grep KillUserProcesses で確認し、該当する場合は systemd-run --user --scope または systemd サービス化を検討してください。
  2. OOM Killer(メモリ不足)による強制終了
    SIGHUP 以外の原因(メモリ枯渇)でカーネルに殺された可能性があります。dmesg -T | grep -i oom または journalctl -k | grep -i oom で確認してください。
  3. OS/サーバーの再起動
    uptime コマンドでサーバー自体が再起動していないか確認してください(nohup はOS再起動には耐えられません)。

Q2. nohup.out のログが肥大化してディスクを圧迫しています

実行時に /dev/null へ捨てるか、logrotate 等でローテーション管理される専用ディレクトリへ出力先を指定してください。

# ログ破棄
nohup ./worker.sh > /dev/null 2>&1 &

Q3. コマンドの起動自体に失敗したか確認するには?

nohup は起動失敗時に固有の終了ステータスを返します。

  • 127:指定したコマンドが見つからない(パスの間違いなど)
  • 126:コマンドは見つかったが実行権限がない(chmod +x が必要)
  • 125nohup 自体のエラー(出力先への書き込み権限不足など)

バックグラウンド実行時はログファイルの先頭行に nohup: failed to run command... と記録されているかを確認してください。

まとめ

nohup コマンドは、SSH接続の切断に左右されずにバックグラウンドで安全に処理を完遂させるための基本ツールです。

  • 鉄板の基本形nohup command > output.log 2>&1 & を定型として覚える
  • nohup はバックグラウンド化しないため、必ず末尾に & を付ける
  • nohup.out の肥大化防止には明示的なリダイレクト(または /dev/null)を指定する
  • プロセスの確認pgrep -a -f <名前>ps aux停止kill <PID>pkill -f <名前> を使う
  • 永続的なサービス稼働や再起動後の自動復帰が必要な場合は、systemd の利用を検討する

実務での長時間バッチやサーバーメンテナンスにぜひ役立ててください。

Bash玄

はじめまして!Bash玄です。

エンジニアとしてシステム運用に携わる中で、手作業の多さに限界を感じ、Bashスクリプトを活用して業務を効率化したのがきっかけで、この道に入りました。「手作業は負け」「スクリプトはシンプルに」をモットーに、誰でも実践できるBashスクリプトの書き方を発信しています。

このサイトでは、Bashの基礎から実践的なスクリプト作成まで、初心者でもわかりやすく解説しています。少しでも「Bashって便利だな」と思ってもらえたら嬉しいです!

# 好きなこと
- シンプルなコードを書くこと
- コマンドラインを快適にカスタマイズすること
- 自動化で時間を生み出すこと

# このサイトを読んでほしい人
- Bashに興味があるけど、何から始めればいいかわからない人
- 定型業務を自動化したい人
- 効率よくターミナルを使いこなしたい人

Bashの世界に一歩踏み出して、一緒に「Bash道」を極めていきましょう!

Bash玄をフォローする

コメント