今回はジョブ関係のコマンドです。1980年くらいのUNIX関係の本などにはジョブの説明がありましたが、最近ではあまり見かけないような感じもあります。とはいえシェル上でコマンドを入力すれば、ジョブとして処理されていきます。複数であれ一つであれ入力したコマンド一行分が一つのジョブになります。
ジョブはシェルの管理下になるため、シェルによってはジョブをサポートしていないものもあります。(iPhoneで動くa-shellなど)
ジョブ関係のコマンドは難しくないので、今回は軽めにやっていきましょう。

ジョブの停止と一時停止

最初にジョブの停止方法と一時停止の方法について説明しておきます。
まず、フォアグラウンドで実行されているジョブの停止方法はコントロールキーを押したままCキーを押します。実行されているコマンドを止める場合と同じです。

watch ps

ジョブの実行を完全に停止してしまうのではなく、一時停止させることもできます。ジョブを一時停止させるにはコントロールキーを押したままZキーを押します。これはviなどエディタで編集している場合でも有効です。

vi test.txt

一時停止した処理を再開することもできますが、これは後ほど説明します。

ジョブをバックグラウンドで実行

コマンドを入力するとジョブはフォアグラウンドで実行されます。例えば以下のように入力すると10秒間待ちます。

sleep 10

この状態だと入力したコマンドの処理が終わるまで次のコマンドを入力できません。このような処理に時間がかかる場合はバックグラウンドで処理させておくと便利です。ジョブをバックグラウンドで実行するには、コマンドの最後に&をつけます。1行で複数のバックグラウンド処理を指定することもできます。この場合は&の後に半角空白で区切って次のコマンドを指定します。zshの場合は&の後に;を指定することもできます。

以下のようにするとコマンドはバックグラウンドで処理されます。バックグラウンドで処理されるため、すぐに次のコマンドが入力できる状態になります。

sleep 10 &

ただ、今時はたくさんのターミナル(もしくはタブ)を開いてフォアグラウンドで実行させて管理した方が楽な事もあります。ここらへん時代の流れなのかなと思う事もあります。ターミナルウィンドウとタブの組み合わせにしておけば見た目にも管理しやすいというのもあります。とは言え、限度というものがあるので、そこらへんは上手に使い分ければよいでしょう。

ジョブの確認

ジョブを確認するには以下のようにjobsコマンドを使います。そのまま入力すると現在のジョブが表示されます。ジョブには整数の番号が割り当てられます。jobコマンドで表示される一番左側の[ ]の中に表示される数値がジョブ番号になります。ジョブが終了すると終了時点でメッセージが表示されるか、リターンキーを押した場合にメッセージが表示されます。これは環境によって異なります。

jobs

ジョブ番号をfgコマンドに指定することで一時停止したジョブを再開する事ができます。なお、fgコマンドでジョブ番号を指定する場合、ジョブ番号の前に%をつける必要があります。以下の例ではジョブ番号1の処理をフォアグラウンドにしています。

fg %1

一時停止してしまった処理をバックグラウンドで再開させることもできます。この場合はbgコマンドを使います。bgコマンドの後にジョブ番号を指定します。fgコマンドと同様にジョブ番号の前に%をつける必要があります。

bg %1

ジョブの強制終了

次に実行しているジョブを強制終了させてみましょう。ジョブが予期せぬ動作をしている場合(プログラムが暴走した等)などには必須です。
ジョブの停止はkillコマンドを使います。killコマンドは実行中のプロセスを終了・再起動などを行う事ができます。
ジョブを停止させる場合はkillコマンドにジョブ番号かプロセス番号のいずれかを指定します。シェルでジョブを管理できている場合はジョブ番号を指定した方がよいでしょう。  まず、停止させたいジョブ番号を表示し確認します。

jobs

ジョブ番号だけでなくプロセス番号も表示する場合はjobsコマンドでlオプションを指定します。

jobs -l

ジョブ番号が分かったら以下のようにkillコマンドでジョブ番号を指定することでジョブを終了させる事ができます。ジョブ番号を指定する場合は番号の前に%をつける必要があります。なお、シグナルを示す-KILLを省略してkill %1のように指定することもできます。

kill -KILL %1

ジョブ番号でなくプロセス番号を指定することもできます。なお、ジョブ番号と違い%は不要です。以下の例ではプロセス番号36104の処理を強制終了させています。

kill -KILL 36104

なお、強制終了させるよりも、まず正常に終了させるように-TERMを指定した方がよいでしょう。特に何らかの処理を行っている場合は強制的にプロセスを終了させると後々の処理に不具合を生じさせる可能性があるからです。

kill -TERM 76366

killコマンドで送ることができるシグナルは以下のようにすると表示されます。環境によって使えるシグナルが異なります。

kill -l
  • ubuntu環境

    ubuntu環境

  • RaspberryPI環境

    RaspberryPI環境

  • mac環境

    mac環境

ジョブ管理対象から外す

 ジョブはシェルの管理下にありますが、場合によってはシェルの管理下から切り離したいこともあります。この場合、disownコマンドを使います。disownコマンドの後にジョブ番号を指定します。ジョブから切り離されてもプロセスとして実行されるので処理には問題ありません。

sleep 999 &
jobs -l
disown %1

通常プロセスと切り離されてしまった処理をジョブ管理下に戻すことはできません。

なお、複数のバックグラウンド処理がすべて完了するまで待つにはwaitコマンドを使います。以下のようにすると3つのバックグラウンド処理が終わるとENDの文字が表示されます。

sleep 4 & sleep 6 & sleep 2 & wait; echo "END"
  • ubuntu環境

    ubuntu環境

  • RaspberryPI環境

    RaspberryPI環境

  • mac環境

    mac環境

という事で今回は、これで終わりです。

著者 仲村次郎
いろいろな事に手を出してみたものの結局身につかず、とりあえず目的の事ができればいいんじゃないかみたいな感じで生きております。