Linuxでバックグラウンド実行する方法

Linuxでバックグラウンド実行する方法

Linuxでバックグラウンド実行を扱う場面は、長時間かかる処理を端末を占有せずに動かしたいとき、SSH切断後もジョブを継続したいとき、定期実行や常駐プロセスとして安定運用したいときに集中する。やり方は1つではなく、単発コマンドなら &、切断耐性を持たせるなら nohupdisown、再接続前提なら tmux、本番運用なら systemd と、目的ごとに選ぶのが基本になる。Linuxのバックグラウンド実行は「とりあえず裏で動かす」だけではなく、標準出力の行き先、端末終了時の挙動、プロセス管理方法まで含めて考えると失敗しにくい。

最初に理解しておくべきこと

Linuxでいうバックグラウンド実行には、厳密にはいくつかの段階がある。1つ目は「同じシェルの中で前面実行ではなく裏で動かす」状態。2つ目は「端末を閉じても止まらない」状態。3つ目は「OSにサービスとして監視・再起動してもらう」状態。& だけでは1つ目しか満たさないことがあり、長時間運用では nohuptmuxsystemd のように目的に応じた手段へ切り替える必要がある。

最も簡単な方法はコマンドの末尾に & を付けること

一番手軽なのは、コマンドの末尾に & を付けてバックグラウンドジョブとして起動する方法。これによりシェルはコマンドをバックグラウンドジョブとして扱い、プロンプトへすぐ戻りやすくなる。短時間で終わる処理や、端末を閉じない前提の補助実行ならこれだけでも十分なことがある。GNU Bashのジョブ制御は、フォアグラウンド・バックグラウンド・再開・停止をシェル内部で扱う仕組みとして設計されている。

python long_task.py &

& だけでは端末終了時に止まることがある

初心者が最も誤解しやすいのがここで、& を付けたからといって必ずしも端末切断後まで安全に動き続けるわけではない。プロセスはシェルや端末との関係を持っていることがあり、ログアウトや端末終了時のシグナルの影響を受ける場合がある。そのため、SSHでサーバーへ入って実行している長時間処理を「ただ & で流すだけ」にすると、切断後に停止することがある。

実行中ジョブを確認するには jobs を使う

同じシェルの中でバックグラウンドに回したジョブを確認したいときは jobs が基本になる。これはシェルのジョブ制御情報を表示するもので、PIDそのものではなく、シェルが把握しているジョブ番号や状態を確認する用途に向いている。複数のバックグラウンド実行を並べたときに「まだ生きているか」「停止しているか」を見る入口として使いやすい。

jobs

バックグラウンドへ回したジョブを前面に戻す方法

バックグラウンドへ回した処理を、もう一度前面で操作したくなることがある。そのときは fg を使う。逆に、前面で実行中の処理を一時停止してバックグラウンドへ送りたいなら、一般的には Ctrl + Z で停止し、その後 bg で再開する流れになる。Bashのジョブ制御はこの前面・背面の切り替えを標準機能として持っている。

実行中に Ctrl + Z で一時停止
bg
fg

端末を閉じても継続したいなら nohup が定番

SSH切断や端末終了後も処理を継続させたいなら、nohup は基本的な選択肢になる。nohup はハングアップシグナルの影響を受けにくくし、標準出力と標準エラー出力をファイルへ逃がしながら実行する用途でよく使われる。単発の長時間バッチ、学習済みモデルの生成、CSV出力のように「今すぐ裏で回したいが、まだ systemd までは要らない」ケースで扱いやすい。

nohup python long_task.py > app.log 2>&1 &

nohup を使うときはログ出力先を明示する

nohup を付けただけで満足すると、標準出力が nohup.out に流れて「どこにログが出たのか分からない」状態になりやすい。実務では、標準出力と標準エラーを明示的にログファイルへ向ける方が扱いやすい。特にエラー調査では 2>&1 を付けてエラー出力も同じファイルへまとめると確認しやすい。バックグラウンド実行で最も困るのは「落ちたのに何も見えない」ことなので、出力先の明示はかなり重要になる。

nohup bash backup.sh > /var/log/backup.log 2>&1 &

disown はシェル管理からジョブを切り離すときに使う

すでに起動済みのジョブを、現在のシェル管理から切り離したいときは disown が使える。これは新しいプロセスを起動するコマンドではなく、現在のシェルが持っているジョブ管理テーブルから対象ジョブを外すためのもの。うっかり通常実行してしまった処理を Ctrl + Zbgdisown という流れで救済する使い方がある。ただし、これはあくまでシェルからの切り離しであり、サービス監視や再起動までしてくれるわけではない。

python long_task.py

実行中に Ctrl + Z
bg
disown

再接続して作業を続けたいなら tmux が非常に強い

長時間処理をただ動かすだけでなく、後から同じ端末状態へ戻ってログを見たり手作業を続けたりしたいなら、tmux が非常に強い。tmux はターミナルマルチプレクサで、セッションをデタッチしてもプロセスを継続させ、後から再接続できる。公式のtmux Wikiでも、セッションを切り離してもバックグラウンドで走り続け、後で再接続できることが特徴として説明されている。SSH先サーバーでの長時間作業では、最初から tmux セッションの中で動かすだけで事故をかなり減らしやすい。

tmux new -s work
python long_task.py

tmux の基本操作は new / detach / attach を覚える

tmux を使うなら最低限覚えるのはこの3つで十分なことが多い。新しいセッションを作る new-session、現在の画面から切り離す detach、後から戻る attach。tmux Wikiの Getting Started でも、tmux new -Asmysession のように、既存があれば接続し、無ければ新規作成する使い方が案内されている。サーバー作業ではこの1コマンドだけでもかなり便利になる。 :contentReference[oaicite:10]{index=10}

tmux new -s mysession

デタッチは Ctrl + b のあと d

tmux attach -t mysession
tmux ls

本番運用の常駐処理は systemd で管理するのが基本

アプリケーションサーバー、ワーカー、常駐スクリプトのように「落ちても再起動したい」「起動順や自動起動も管理したい」プロセスは、&nohup ではなく systemd で管理する方が安定する。systemd の service ユニットは、プロセスをOSが監視し、起動・停止・再起動・ログ管理・自動起動などを扱う仕組みとして設計されている。Linuxの現代的な常駐プロセス運用では、systemd.service や daemon の考え方に寄せる方が再現性と保守性が高い。

sudo nano /etc/systemd/system/myapp.service

[Unit]
Description=My Background App
After=network.target

[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/myapp
ExecStart=/usr/bin/python3 /home/ubuntu/myapp/app.py
Restart=always

[Install]
WantedBy=multi-user.target

systemd サービスとして有効化する基本手順

systemd ユニットファイルを作ったら、設定の再読込、有効化、起動、状態確認の順で進めるのが基本になる。これにより、手動起動だけでなく、OS再起動後も自動的に立ち上がるようにできる。単発の実験では重いが、本番バッチやワーカーではこの差が非常に大きい。

temctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp
sudo systemctl status myapp

ログ確認は方法ごとに変わる

バックグラウンド実行で困りやすいのは「今どうなっているか分からない」こと。そのため、実行方法ごとにログ確認の方法を意識しておく必要がある。nohup ならリダイレクト先ファイル、tmux ならアタッチして画面確認、systemd なら journalctl が基本になる。プロセスを裏に回すだけでログを残さない設計にすると、トラブル時の切り分けが非常に難しくなる。

tail -f app.log
sudo journalctl -u myapp -f

PID 管理と停止方法も最初から意識する

バックグラウンドで動かしたあと、止め方が分からなくなるのもよくある失敗。単発プロセスなら pspgrep でPIDを見つけて kill、tmux ならセッション単位で終了、systemd なら systemctl stop が基本になる。実行方法ごとに止め方が違うため、「起動は簡単だが停止手順が曖昧」という状態は避けた方がよい。

ps aux | grep python
pkill -f long_task.py

tmux kill-session -t mysession

sudo systemctl stop myapp

よくある失敗と発生条件

Linuxのバックグラウンド実行でよくある失敗はかなり典型的。& だけで満足してSSH切断後に止まる、nohup を使ったがログの出力先が分からない、tmux を使わず長時間作業をそのままSSH上で流して接続断で消える、systemd を使うべき常駐処理を nohup で運用して再起動や障害復旧が不安定になる、といったものが多い。つまり、「とりあえず裏で実行したい」のか、「切断後も続けたい」のか、「サービスとして安定運用したい」のかを曖昧にしたまま手段を選ぶと失敗しやすい。

実務での使い分けの目安

単発のちょい実行なら &。SSH切断後も続けたい単発処理なら nohup。あとで戻って画面を見ながら作業したいなら tmux。本番のワーカーやサーバーのように、落ちたら困る常駐処理なら systemd。この使い分けを最初から決めておくと、バックグラウンド実行まわりのトラブルはかなり減らしやすい。特にサーバー運用では、「長時間処理はまず tmux で始める」「継続運用するものは最終的に systemd 化する」という流れが現実的で扱いやすい。

まとめ

Linuxでバックグラウンド実行する方法は1つではなく、目的ごとに最適解が違う。& は手軽だが切断耐性は弱く、nohup は単発の長時間実行に向き、tmux は再接続前提の作業に強く、systemd は本番の常駐サービス管理に向いている。最も大切なのは、プロセスを裏で動かすこと自体ではなく、「端末を閉じたらどうなるか」「ログはどこへ出るか」「どう止めるか」「落ちたら再起動するか」を先に決めて選ぶことになる。