長時間かかる処理を実行しながら他の作業を続けたいとき、Linuxの「ジョブ管理」が役立ちます。 コマンドをバックグラウンドで動かしたり、一時停止・再開したりする基本操作を身につけましょう。
フォアグラウンドとバックグラウンドとは
コマンドを普通に実行すると、そのコマンドが終わるまでターミナルが占有されます。これをフォアグラウンド実行といいます。
一方、コマンドをターミナルに返しながら裏で動かし続けることをバックグラウンド実行といいます。
コマンドをバックグラウンドで起動する(&)
コマンドの末尾に & を付けると、最初からバックグラウンドで起動できます。
sleep 60 &
実行すると次のように表示されます。
[1] 12345
[1] はジョブ番号、12345 はプロセスID(PID)です。
ジョブ一覧を確認する(jobs)
現在のシェルで実行中・停止中のジョブを一覧表示します。
jobs
[1]- Running sleep 60 &
[2]+ Stopped vim notes.txt
+ は最後に操作したジョブ(カレントジョブ)、- はその一つ前のジョブを示します。
フォアグラウンドジョブを一時停止する(Ctrl+Z)
フォアグラウンドで動いているコマンドを一時停止して、シェルに制御を返します。
vim notes.txt
# ↑ 編集中に Ctrl+Z を押す
[1]+ Stopped vim notes.txt
ジョブは停止状態になり、後で再開できます。
ジョブをバックグラウンドで再開する(bg)
停止中のジョブをバックグラウンドで再開します。
bg %1
%1 はジョブ番号1を指します。% を省略してジョブ番号だけでも指定できます。
bg 1
カレントジョブ(+ マーク)を対象にする場合は番号を省略できます。
bg
ジョブをフォアグラウンドに戻す(fg)
バックグラウンドや停止中のジョブをフォアグラウンドに持ってきます。
fg %1
典型的なワークフロー
重いビルドを走らせながら別のファイルを編集する例です。
# ビルドをバックグラウンドで起動
make build &
# ファイルを編集(フォアグラウンドで起動)
vim src/main.c
# 編集が終わったらビルドの状態を確認
jobs
# ビルドをフォアグラウンドに戻して完了を待つ
fg %1
ログアウトしても実行し続ける(nohup)
通常のバックグラウンドジョブは、シェルを閉じると終了します。
ログアウト後も処理を続けたい場合は nohup を使います。
nohup ./long-running-script.sh &
出力は nohup.out に書き込まれます。出力先を変えたい場合はリダイレクトします。
nohup ./backup.sh > backup.log 2>&1 &
ジョブを強制終了する(kill)
ジョブを終了させたいときは kill にジョブ番号を渡します。
kill %1
PIDを使って終了させることもできます。
kill 12345
強制終了には -9 シグナルを使います(最終手段)。
kill -9 12345
練習問題
問題 1
以下のコマンドを実行し、ジョブ番号と状態を確認してください。
sleep 120 &
sleep 200 &
jobs
このとき jobs の出力はどのようになりますか?
問題 2
フォアグラウンドで sleep 300 を起動し、Ctrl+Z で一時停止した後、バックグラウンドで再開してください。その後 jobs で状態を確認し、最後にそのジョブを終了させてください。
問題 3
echo "done" > result.txt をログアウト後も実行できるコマンドに書き換えてください。
練習問題の答え
答え 1
[1]- Running sleep 120 &
[2]+ Running sleep 200 &
2つのジョブがどちらも Running 状態で表示されます。[2] が最後に起動したジョブなので + が付きます。
答え 2
# フォアグラウンドで起動
sleep 300
# Ctrl+Z で一時停止(表示例)
# [1]+ Stopped sleep 300
# バックグラウンドで再開
bg %1
# 状態確認
jobs
# [1]+ Running sleep 300 &
# ジョブを終了
kill %1
答え 3
nohup sh -c 'echo "done" > result.txt' &
または、スクリプトファイルに書き出す方法もあります。
echo 'echo "done" > result.txt' > myscript.sh
chmod +x myscript.sh
nohup ./myscript.sh &