これまで
シェルもどき「oreshell」を自作している。
前回は、Unix(とその眷属)のシェルにおけるジョブとは何かについて調べた。
今回はジョブ制御とその仕組みについて調べる。
ジョブは3つの状態を持つ。
これら3つの状態への切り替え、現在の状態の確認をジョブ制御で行う。
bashではジョブの現在の状態の確認は内部コマンド「jobs」で行う。
以下はその例。
bashではジョブの実行状態の切り替えを内部コマンド「fg」「bg」で行う。
また、端末からは「Ctrl+Z」「Ctrl+C」の入力によりジョブの実行状態を切り替える。
状態遷移図を以下に示す。
(他にも状態を切り替える方法(killコマンドなど)はあるがここでは割愛)
状態遷移図のイベントa~gを実行してみる。
まずbash内部コマンドjobsを実行してジョブの状態を確認する。
現時点では、このbash上にジョブは一つも存在しない。
ここではpingコマンドを実行する。実行するとpingが繰り返し実行し、結果を永久に標準出力する。
端末に「Ctrl+Z」を入力すると、先に実行したpingコマンドが停止する。
ここでbash内部コマンドjobsを実行してジョブの状態を確認する。
ジョブが1つ存在する。ジョブ番号は1番、内容は「ping yahoo.co.jp」、状態は「停止」。
ジョブ番号1番を指定してbash内部コマンド「fg」を実行すると、停止していたジョブ番号1番の「ping yahoo.co.jp」が実行を再開する。
端末に「Ctrl+C」を入力すると、pingコマンドが強制終了した。
pingコマンドを末尾に「&」をつけて実行する。
実行するとこのジョブが1番であることを表示する。
その後pingが繰り返し実行し、結果を永久に標準出力する。
a)の場合と違って、ここで端末から「Ctrl+Z」や「Ctrl+C」を入力してもこのpingを停止したり強制終了することはできない。これはこのpingがバックグラウンドジョブであるため。
ジョブ番号1番を指定してbash内部コマンド「fg」を実行すると、バックグラウンドジョブのpingがフォアグラウンドジョブに切り替わる。
相変わらずpingの結果を標準出力し続ける。
一旦、「Ctrl+Z」で停止する。
その後、
ジョブ番号1番を指定してbash内部コマンド「bg」を実行する。実行するとこのジョブが1番であることを表示する。
その後pingがバックグラウンドジョブとして実行を再開する。
このpingで確認したいことは終わったのでf),d)で強制終了する。(f,d)
今度はpingを回数を指定する。コマンド末尾に「&」をつけて実行する。
pingが指定回数だけ処理を実行すると終了する。
この状態でエンターキーを押すとジョブの終了を表示する。
今度は状態遷移図ではなくロバストネス図で考えてみる。
ここではキーボードからはじまり、実行中または停止中のジョブまでの間のリクエストの伝播に絞って考える。
端末からCtrl+Zを入力するとジョブは停止状態になる。(状態遷移図のb)
端末からCtrl+Cを入力するとジョブは終了する。(状態遷移図のd)
bash内部コマンド「fg %1」を実行するとジョブはフォアグラウンドで実行を再開する。(状態遷移図のc)
bash内部コマンド「bg %1」を実行するとジョブはバックグラウンドで実行を再開する。(状態遷移図のg)
端末、またはbashからジョブに向けて「何か」が送られている。
この「何か」の正体は「シグナル」である。
次回はシグナルの話。