サーバー管理やプログラミングにおいて、コマンドを実行している最中に端末を閉じてしまうと、実行中のプロセスが中断してしまうことがあります。特に長時間実行が必要なプロセスにおいては、そのリスクが深刻です。そんなときに役立つのがnohupコマンドです。この記事では、nohupの基本的な使い方から、プロセス確認・停止方法、効果的な活用法まで詳しく解説します。
最小構成:SSH接続を切ってもコマンドを止めない例
SSHでサーバーに接続して作業しているとき、接続が切れた瞬間に実行中のコマンドが止まってしまうのを防ぎたい場合は、次の1行を覚えておけば十分です。
# サーバーにSSH接続した状態で実行
nohup ./long-task.sh > output.log 2>&1 &
# [1] 12345 ← ジョブ番号とPIDが表示される
# そのままターミナルを閉じたり、SSH接続が切れても続行される
後で再度SSH接続したときは、PIDでプロセスの生存確認、ログファイルで進捗確認ができます。
# 再接続後
ps -p 12345
tail -f output.log
ポイントは、nohupだけでは処理はバックグラウンドに回らないため、末尾の&と必ずセットで使うことです。次の章から、この1行を構成する各要素と、確認・停止までの一連の流れを順番に解説します。
nohupとは?
nohup(「no hang up」の略、読み方は「のーはっぷ」)は、LinuxやUnixシステムで使用されるコマンドです。通常、シェルを閉じたりログアウトしたりすると、端末からSIGHUP(ハングアップシグナル)が送られ、そのセッション内で実行されていた全てのプロセスが中断されます。nohupを使用することで、このSIGHUPを無視してプロセスをバックグラウンドで継続して実行できます。
構文
nohup COMMAND [ARG...]
# 実運用ではたいてい &(バックグラウンド化)と併用
nohup COMMAND [ARG...] &
# 代表的なリダイレクトの組み合わせ
nohup COMMAND </dev/null >nohup.out 2>&1 &
- 標準入力が端末なら
/dev/nullに、標準出力が端末ならnohup.out(カレントディレクトリ、または$HOME/nohup.out)へ、標準エラーが端末なら標準出力へ自動リダイレクトされます(追記モード)。 - パイプライン全体を保護したい場合は、
sh -c '…'など1コマンドに包むのが確実です。
nohupの基本的な使い方
nohupは非常にシンプルに使用することができます。通常のコマンドの前にnohupを追加し、末尾に&を付けてバックグラウンドで実行します。
nohup your-command &
実行例
例えば、何らかの長時間処理を行うスクリプトlong-running-script.shをバックグラウンドで実行したい場合、以下のようにすれば良いです。
nohup ./long-running-script.sh &
tail -f nohup.out
実行すると以下のようなメッセージが表示され、出力はnohup.outに追記されます。
nohup: ignoring input and appending output to 'nohup.out'
このnohup.outはコマンド実行時のカレントディレクトリに生成されます。カレントに書けない場合は$HOME/nohup.outが使われます。
nohupと&の違い
&だけでバックグラウンド実行しても、端末を閉じるとSIGHUPが送られてプロセスが終了します。nohupの役割はそのSIGHUPを無視させることです。この2つは目的が異なるため、セットで使うのが基本です。
| コマンド | バックグラウンド | 端末を閉じたとき | 標準出力 |
|---|---|---|---|
command & |
○ | 終了(SIGHUP) | 端末 |
nohup command |
×(フォアグラウンド) | 継続 | nohup.out |
nohup command & |
○ | 継続 | nohup.out |
# NG: 端末を閉じるとプロセスが終了する
./long-task.sh &
# OK: 端末を閉じてもプロセスが継続する
nohup ./long-task.sh &
すでに&で動かしているプロセスを後から切り離したい場合は、disownコマンドが使えます。
./long-task.sh &
# [1] 12345
disown %1 # ジョブをシェルから切り離す
nohupでの出力リダイレクト
nohupで実行されたコマンドの標準出力とエラー出力はデフォルトでnohup.outにリダイレクトされますが、任意のファイルにリダイレクトしたい場合は以下のように指定できます。
nohup ./your-command > output.log 2>&1 &
ここで> output.logが標準出力をoutput.logにリダイレクトし、2>&1が標準エラー出力も同じファイルにリダイレクトしています。これによって、コマンド実行のすべての出力ログを一元管理できます。
nohup command > output.log 2>&1 &の各部分
| 要素 | 役割 |
|---|---|
nohup |
後続のコマンドにSIGHUPを無視させる。単体ではバックグラウンド化しない |
command |
実際に実行したいコマンドやスクリプト |
> output.log |
標準出力(fd 1)をoutput.logへ書き込む(上書き) |
2>&1 |
標準エラー出力(fd 2)を、その時点の標準出力の書き込み先(output.log)へ合流させる |
& |
シェルにジョブとしてバックグラウンドで実行させる |
2>&1は必ず> output.logより後ろに書きます。順序を逆にすると、標準エラーは端末(リダイレクト前の出力先)に向いたままになり、output.logには標準出力しか記録されません。
出力先を指定した実行例
nohup ./server --port 8080 > /var/log/myserver.log 2>&1 &
エラー例:nohup.outを作れない場所での実行
カレントディレクトリにも$HOMEにも書き込み権限がないと、以下のようなエラーになります。
nohup: failed to open 'nohup.out' for writing: Permission denied
この場合は明示的に出力先を指定してください。
nohup ./your-command > /tmp/output.log 2>&1 &
パイプライン全体を保護する
そのまま nohup cmd1 | cmd2 と書くと、cmd1 しかSIGHUP保護されません。パイプライン全体を保護するには、sh -c で包みます。
nohup sh -c 'cmd1 | cmd2 | gzip > /data/archive.gz' > job.log 2>&1 &
入力を切って端末から完全に独立させる
端末からの入力を一切受けないよう明示することで、完全にデタッチした状態で実行できます。
nohup python worker.py </dev/null > worker.log 2>&1 &
実行中のプロセス確認と停止方法
nohupで起動したプロセスは、以下の方法でPIDを確認して停止できます。
PIDの確認
nohup実行直後にシェルがPIDを表示します。
nohup ./long_task.sh &
# [1] 12345 ← これがPID
同じシェルセッションの中であれば、jobsコマンドでも実行中のジョブ状態を確認できます。
jobs
# [1]+ Running nohup ./long_task.sh &
ただしjobsが管理しているのはそのシェルプロセス自身が抱えているジョブだけです。SSH接続を切って再接続すると新しいシェルが起動するため、以前のjobsの情報は引き継がれません。SSH再接続後や別の端末から確認したい場合は、psやpgrepのようにプロセス自体を直接検索するコマンドを使います。
# コマンド名で検索
ps aux | grep long_task.sh
# プロセス名で直接検索
pgrep -l long_task
プロセスの停止
# PIDを指定して停止
kill 12345
# 強制停止(通常のkillで止まらない場合)
kill -9 12345
# プロセス名で一括停止
pkill -f long_task.sh
並行処理とnohupの組み合わせ
nohupは、並行して複数のプロセスを管理する場合にも非常に有効です。例えば、以下のように複数のコマンドを同時にバックグラウンドで実行することができます。
nohup command1 &
nohup command2 &
nohup command3 &
これによって、複数のプロセスを同時に立ち上げ、それぞれの進行を確認するために事務作業の手間を大幅に省くことができます。
効果的な活用法
nohupを活用することによって、特定の状況下で業務効率を上げることが可能です。ここでは、nohupを使ったいくつかの効果的な活用法をご紹介します。
長時間のバッチ処理
データベースのバックアップや大規模なファイル転送、複雑な計算処理など、長い時間がかかるバッチ処理にnohupを使うとセッションが切れても継続できます。
# DBダンプをバックグラウンドで実行(ログは /var/log/ に保存)
nohup mysqldump -u root mydb > /backup/mydb.sql 2> /var/log/dump.log &
# 大容量ファイルの転送
nohup rsync -avz /data/ user@remote:/backup/ > /var/log/rsync.log 2>&1 &
# 進捗はtailでリアルタイム確認
tail -f /var/log/rsync.log
サーバー運用
SSHでリモートサーバーに接続してメンテナンスする際、セッションが切れてもプロセスを継続させられます。Webサーバーや常駐プロセスの起動にも使えます。
# SSH越しにサーバーを起動(セッションが切れても動き続ける)
nohup python app.py --host 0.0.0.0 --port 8080 > /var/log/app.log 2>&1 &
# OSアップデートなど長時間メンテナンス
nohup apt-get upgrade -y > /var/log/upgrade.log 2>&1 &
echo "PID: $!"
開発環境でのテスト
長時間実行されるテストやビルドをnohupでバックグラウンドに回すことで、端末を別作業に使えます。
# テストをバックグラウンドで実行
nohup ./run-tests.sh > test.log 2>&1 &
# 完了を監視
tail -f test.log
sudoとの組み合わせ
root権限が必要なコマンドをnohupで実行する場合はsudoと組み合わせます。
sudo nohup ./system-maintenance.sh > /var/log/maintenance.log 2>&1 &
&・disown・tmux/screen・systemdとの使い分け
nohup以外にも、コマンドを継続実行させる手段はいくつかあります。SSH切断・シェル終了・OS再起動それぞれでの挙動をまとめると、次のようになります。
| 手段 | SSH切断/ログアウト | シェル終了 | OS再起動 | 後から出力確認 | 追加インストール |
|---|---|---|---|---|---|
command &のみ |
停止(SIGHUP) | 停止 | 停止 | 不可(端末に直接出力) | 不要 |
nohup command & |
継続 | 継続 | 停止 | nohup.out/指定ログ | 不要 |
command &+disown |
継続 | 継続 | 停止 | リダイレクト先次第 | 不要 |
| tmux / screen | 継続(デタッチ) | 継続 | 停止 | セッションに再接続して確認 | 要インストール |
| systemdサービス化 | 継続 | 継続 | 継続可(自動起動設定時) | journalctl等 |
ユニットファイル作成 |
nohup・disown・tmux/screenは、いずれもSSH切断やシェル終了には強い一方、OSそのものを再起動するとプロセスは失われます。再起動をまたいで自動的に処理を復帰させたい場合は、これらでは対応できず、systemdでサービス化し再起動時の自動起動(enable)や異常終了時の再起動(Restart=)を設定する必要があります。用途としては、単発のバッチ処理やその場しのぎの継続実行ならnohup、作業内容を後から目視で確認しながら操作したいならtmux/screen、恒常的に動かし続けたいサービスならsystemd、が基本的な使い分けの目安です。
関連コマンド
disown:シェルが送るSIGHUP対象からジョブを外す(Bash/Zsh)。すでにバックグラウンドで動いているプロセスを後から切り離す際に使います。setsid:新しいセッションで実行(端末からの切り離しをさらに強化)。bg:停止中のジョブをバックグラウンドで再開する。nohupと組み合わせてジョブを管理できます。jobs:現在のシェルが抱えるジョブの状態を表示する。同一セッション内での簡易確認に使います。ps:実行中のプロセスを表示する。nohupで起動したプロセスをPIDやコマンド名から探す際に使います。screen/tmux:デタッチ可能な仮想端末で長時間作業。ログアウト後に再接続して出力を確認できます。kill:プロセスにシグナルを送って停止する。nohupで起動したプロセスの終了に使います。systemctl/systemd-run:サービス化やワンショット実行で確実に常駐させる方法。再起動をまたいで継続させたい場合はこちらを検討します。at/batch:後で/負荷低下時にジョブを実行するスケジューリング。
注意点
nohupの使用は非常に便利ですが、注意すべき点もあります。
- プロセスが終了する前に端末を閉じると、
nohupの出力ログを確認するまで状況を把握しにくくなります。出力先を明示的に指定し、tail -fで定期的に確認するのがおすすめです。 - 多くのプロセスをバックグラウンドで走らせると、サーバー負荷が高くなる場合があるので、リソース管理には注意が必要です。
nohupは「SIGHUP無視」が主目的で、制御端末の完全な切断や作業ディレクトリの保持などは別問題です。サービスとして確実に常駐させるならsystemdなどのプロセス管理ツールを使いましょう。- POSIX に準拠しており、GNU/BSD/BusyBox環境で概ね同じ動作をしますが、メッセージや細部に違いがあります。
よくある質問
Q. nohup.out が大きくなりすぎます。どうすればよいですか?
実行時に出力先を明示的に指定するか、/dev/null に捨てることで nohup.out の肥大化を防げます。
# 出力を任意のファイルに
nohup ./script.sh > /var/log/myapp.log 2>&1 &
# ログが不要な場合は捨てる
nohup ./script.sh > /dev/null 2>&1 &
Q. nohup で起動したプロセスを後から確認する方法は?
PIDを事前に記録しておくのが確実です。$! でバックグラウンド起動したプロセスのPIDを取得できます。
nohup ./script.sh > app.log 2>&1 &
echo "PID: $!" > /tmp/myapp.pid
# 後から確認
cat /tmp/myapp.pid
ps -p $(cat /tmp/myapp.pid)
Q. nohup と screen/tmux はどちらを使うべきですか?
用途で使い分けます。nohup はシンプルなバックグラウンド実行に向いており、追加インストール不要です。screen や tmux は「後から接続して出力を確認したい」「複数の仮想端末を使いたい」場合に向いています。継続的なサーバー運用には systemd によるサービス化が最も堅牢です。
Q. nohup で実行したプロセスが終了したかどうかを確認する方法は?
# PID 12345 が生きているか確認
ps -p 12345
# 存在しない場合は何も表示されない
kill -0 12345 && echo "生きています" || echo "終了しています"
# ログファイルの末尾を確認
tail -f nohup.out
Q. Windowsでnohupと同等のことをするには?
WindowsのPowerShellでは Start-Process コマンドや nssm(Non-Sucking Service Manager)を使います。WSL(Windows Subsystem for Linux)環境ではLinuxと同様に nohup が使えます。
まとめ
nohupは、長時間実行が必要なプロセスをログアウトや端末切断後も継続させるための非常に強力なツールです。基本的な使い方はコマンドの前にnohupを付けて末尾に&を加えるだけですが、出力リダイレクト、パイプライン保護、プロセス管理などを組み合わせることで、さらに柔軟に活用できます。長時間のバッチ処理やサーバー運用などの場面でぜひ活用してください。

コメント