2026年5月17日
2026年5月17日
Linuxのジョブ制御の使い方|bg・fg・jobs・Ctrl+Zでジョブを切り替える
ターミナルで時間のかかるコマンドを実行していると、終わるまで次のコマンドを打てません。bash などのシェルのジョブ制御を使うと、コマンドを後ろで動かしたまま別の作業をしたり、途中で止めたコマンドを再開したりできます。
この記事の出力例は、2026年10月時点の Debian 13 の bash 5.2 で確認したものです。zsh でもほぼ同じ操作ができます。
ジョブとフォアグラウンド・バックグラウンド
シェルから起動したコマンド(パイプでつないだ一連のコマンドを含む)をジョブと呼びます。ジョブには次の状態があります。
| 状態 | 意味 |
|---|---|
| フォアグラウンド | 端末を占有して動いている。キーボード入力を受け取れる。1つだけ |
| バックグラウンド(Running) | 端末を占有せずに動いている。プロンプトに戻って別のコマンドを打てる |
| 停止(Stopped) | 一時停止している。fg か bg で再開するまで動かない |
使う操作は次のとおりです。
| 操作 | 働き |
|---|---|
コマンド & |
バックグラウンドで起動する |
Ctrl+Z |
フォアグラウンドのジョブを一時停止する |
jobs |
ジョブの一覧を表示する |
fg |
ジョブをフォアグラウンドに移す(停止中なら再開する) |
bg |
停止中のジョブをバックグラウンドで再開する |
kill %番号 |
ジョブにシグナルを送る(既定は終了) |
バックグラウンドで実行する(&)
コマンドの最後に & を付けると、バックグラウンドで起動してすぐにプロンプトに戻ります。
$ sleep 300 &
[1] 7
$ echo $!
7
[1] がジョブ番号、7 がプロセス ID です。直前にバックグラウンドで起動したプロセスの ID は $! で取り出せます。
バックグラウンドのジョブが出力するメッセージは、そのまま端末に表示されます。画面が乱れるのを避けたいときは、出力をファイルに向けておきます。
./backup.sh > backup.log 2>&1 &
実行中のコマンドを一時停止する(Ctrl+Z)
フォアグラウンドで動いているコマンドは、Ctrl+Z で一時停止できます。
$ vim memo.txt
(vim の画面で Ctrl+Z を押す)
[1]+ Stopped vim memo.txt
$
停止したジョブはその場で止まっているだけで、終了してはいません。エディターを開いたまま一度シェルに戻り、確認のコマンドを打ってからエディターに戻る、といった使い方ができます。
Ctrl+C は一時停止ではなく、フォアグラウンドのジョブを中断(終了)させる操作です。
ジョブの一覧を見る(jobs)
$ sleep 300 &
[1] 7
$ sleep 200 &
[2] 8
$ jobs
[1]- Running sleep 300 &
[2]+ Running sleep 200 &
番号の後ろの記号は次の意味です。
+:カレントジョブ。fgやbgで番号を省いたときに対象になる-:その1つ前のジョブ
よく使うオプションは次のとおりです。
| コマンド | 表示 |
|---|---|
jobs -l |
プロセス ID も表示する |
jobs -p |
プロセス ID だけを表示する |
jobs -r |
実行中のジョブだけを表示する |
jobs -s |
停止中のジョブだけを表示する |
$ jobs -l
[1]- 7 Running sleep 300 &
[2]+ 8 Running sleep 200 &
jobs に出るのは、そのシェルから起動したジョブだけです。別の端末や別の SSH セッションで起動したものは表示されません。それらは ps や pgrep で探します。
ジョブを指定する(%)
fg・bg・kill などでは、ジョブを % で指定します。
| 書き方 | 対象 |
|---|---|
%1 |
ジョブ番号1 |
%+ または %% |
カレントジョブ(+ の付いたジョブ) |
%- |
1つ前のジョブ(- の付いたジョブ) |
%sleep |
コマンド名が sleep で始まるジョブ |
%?log |
コマンドラインに log を含むジョブ |
%sleep のように名前で指定するとき、当てはまるジョブが複数あるとエラーになります。その場合は番号で指定します。
フォアグラウンドに戻す(fg)
$ fg %1
vim memo.txt
fg は指定したジョブを端末の前面に戻します。停止中のジョブなら再開もします。番号を省くと、カレントジョブ(+)が対象です。
停止したジョブをバックグラウンドで再開する(bg)
& を付け忘れて長い処理を始めてしまったときは、Ctrl+Z で止めてから bg でバックグラウンドに回せます。
$ tar czf site.tar.gz /var/www/html
(Ctrl+Z を押す)
[1]+ Stopped tar czf site.tar.gz /var/www/html
$ bg %1
[1]+ tar czf site.tar.gz /var/www/html &
$ jobs
[1]+ Running tar czf site.tar.gz /var/www/html &
bg は停止中のジョブを対象にします。すでに実行中のジョブには効果がありません。
バックグラウンドのジョブがキーボードから入力を読もうとすると、そのジョブは停止します(jobs では Stopped と表示されます)。パスワードの入力などを求めるコマンドは、fg で前面に戻して入力します。
ジョブを終了させる(kill)
kill にはプロセス ID の代わりにジョブを指定できます。
$ kill %2
$ jobs
[1]- Running sleep 300 &
[2]+ Terminated sleep 200
kill は既定で SIGTERM(終了の依頼)を送ります。応答しないときだけ kill -KILL %2(kill -9)で強制終了します。停止中のジョブも kill で終了できます。
ジョブが終わると、次にプロンプトが表示されるときに Done(正常終了)や Terminated(シグナルで終了)と知らせが出て、一覧から消えます。
シェルを閉じたときのジョブの扱い
ジョブはシェルの子プロセスなので、シェルを閉じるときの扱いに注意が必要です。
- 停止中のジョブがある状態で
exitすると、There are stopped jobs.と表示されてシェルは終了しません。続けてもう一度exitすると、停止中のジョブは終了させられます。 - SSH の切断や端末のウィンドウを閉じたときは、シェルが
SIGHUPを受け取り、実行中・停止中のジョブにもSIGHUPを送ります。多くのコマンドはこれで終了します。
ログアウトしても処理を続けたいときは、次のどれかを使います。
disown:起動済みのジョブを切り離す
$ ./import.sh > import.log 2>&1 &
[1] 1234
$ disown %1
$ jobs
$
disown は、ジョブをシェルのジョブ一覧から外し、シェルの終了時に SIGHUP が送られないようにします。一覧から外したくない場合は disown -h %1 とします。停止中のジョブは、先に bg で再開してから disown します。
nohup:最初から切断に強くしておく
nohup ./import.sh > import.log 2>&1 &
nohup は、コマンドが SIGHUP を無視するようにして起動します。出力先を指定しないと、出力はカレントディレクトリーの nohup.out に書かれます。
もっと長く・安定して動かしたい場合
SSH が切れても作業画面ごと残しておきたいときは tmux や screen を使います。サーバーで常に動かしておく処理は、ジョブ制御ではなく systemd のサービスとして登録するほうが、再起動後の自動起動やログの管理まで任せられます。
シェルスクリプトでの使い方
スクリプトの中では、& で複数の処理を同時に起動し、wait で終わるのを待つ使い方が一般的です。
#!/bin/bash
gzip -k access.log &
gzip -k error.log &
wait
echo "すべての圧縮が終わりました"
wait は、そのシェルが起動したバックグラウンドの処理がすべて終わるまで待ちます。wait $! のようにプロセス ID を指定すると、その処理だけを待ちます。スクリプトでは通常ジョブ制御が無効なので、fg や bg は使わず & と wait で組み立てます。
まとめ
コマンド &でバックグラウンドで起動し、$!でプロセス ID を取り出せるCtrl+Zで一時停止、fgで前面に戻す、bgで後ろで再開するjobs(-lで PID つき)で一覧を見て、%1・%+・%-・%名前でジョブを指定するkill %番号で終了させる。既定はSIGTERM- ログアウト後も続けたい処理は
disown・nohup、長く使うならtmuxや systemd を使う
関連記事: