フォアグラウンドとバックグラウンド
ビルドを流している間、その端末では何もできない
数分かかるコマンドを打つと、終わるまでプロンプトが戻ってきません。その間、同じ端末では調べ物も編集もできません。シェルがそのコマンドに端末の主導権を丸ごと渡しているからで、この状態をフォアグラウンドと呼びます。
主導権を渡さずに動かすこともできます。それがバックグラウンドで、プロンプトはすぐ戻ってきて、コマンドは裏で走り続けます。
末尾に & を付けて後ろに回す
ターミナル
$ ./build.sh &
[1] 12345
$ jobs
[1]+ Running ./build.sh &[1] がジョブ番号、12345 が PID です。ジョブ番号はそのシェルの中だけで通じる連番で、シェルを閉じると消えます。PID はマシン全体で一意なので、別の端末から触るときはこちらを使います。
jobs で、今のシェルが抱えているものを一覧できます。裏に回したジョブが全部終わるまで待ちたいときは wait が使えます。
打ってから気づいたときは Ctrl+Z
ターミナル
$ ./build.sh
^Z
[1]+ Stopped ./build.sh
$ bg %1
[1]+ ./build.sh &先に & を付け忘れても、打ち直す必要はありません。Ctrl+Z を押すとそのコマンドは一時停止して、プロンプトが戻ります。ここで bg と打てば、停止したところから裏で再開します。逆に、裏で動いているものに入力が必要になったら fg で手前に戻します。
Ctrl+Z は中断であって終了ではない、というのが大事なところです。押しただけの状態ではコマンドは止まったまま残っているので、そのままシェルを閉じようとすると警告が出ます。
裏に回した出力は、手元の作業に混ざる
ターミナル
$ ./build.sh > build.log 2>&1 &
$ tail -f build.log裏で動いているプロセスも、標準出力はそのまま端末に流れてきます。何か打っている途中に割り込まれるので、まともに作業できません。ファイルに書き出しておいて、見たいときだけ tail -f で覗く形にすると落ち着きます。
2>&1 は、エラーの出力も同じファイルにまとめる指定です。これを忘れると、うまくいかなかったときの手がかりだけが端末に散らばって残ります。
jobsが見えるのは、そのジョブを起動したシェルだけです。別の端末を開いてjobsを打っても何も出ません。他の端末から触りたいときは、ジョブ番号ではなく PID を使います。
課題
- sleep をバックグラウンドで 2 つ起動する
- wait で全ての完了を待つ