私の理解では、 ジョブはパイプラインです は特定のシェルから開始され、このシェル内からこれらのジョブ(fg
、bg
、Ctrl-Z)を管理できます。ジョブは複数のプロセス/コマンドで構成できます。
私の質問は、シェルを含む元のジョブが終了すると、これらのジョブはどうなるのですか? huponexitが設定されていないため、シェルが終了した後もバックグラウンドプロセスが実行を続けるとします。
私がやったとしましょう:
$ run.sh | grep 'abc' &
[1] job_id
次に、このシェルを終了します。新しいシェルに入ってjobs
を実行すると、何も表示されなくなります。しかし、ps aux | grep run.sh
を実行して、このプロセスが実行されていることを確認できます。また、ps aux | grep grep
を実行して、grep 'abc'
のプロセスも実行されていることを確認します。
パイプライン全体のジョブIDを取得して、一度に終了できるようにする方法はありますか?または、元のシェルを終了したら、別のシェルからすべてのプロセスを個別に終了する必要がありますか? (私は後者を試しましたが、うまくいきますが、すべてのプロセスを追跡するのは面倒のようです。)
シェルが終了すると、HUPシグナルがバックグラウンドジョブに送信され、これによりジョブが終了する場合があります。 SIGHUPシグナルは、シェル自体がSIGHUPを受信した場合にのみ送信されます。つまり、ターミナルが終了した場合(たとえば、ターミナルエミュレータープロセスが終了した場合)だけで、シェルを正常に終了した場合(exit
組み込みまたはタイピング Ctrl+D)。詳細については、 ログアウト時にSIGHUPがジョブに送信されない場合 および 子プロセスがその親で停止するUNIXバリアントはありますか? を参照してください。 bashでは、huponexit
オプションを設定して、SIGHUPを通常の終了時にバックグラウンドジョブに送信することもできます。 ksh、bash、zshでは、ジョブでdisown
を呼び出すと、SIGHUPの送信先のジョブのリストから削除されます。 SIGHUPを受信するプロセスは、シグナルを無視またはキャッチする可能性があり、その後、停止しません。プログラムの実行時にNohup
を使用すると、SIGHUPの影響を受けなくなります。
SIGHUPの可能性があるためにプロセスが強制終了されなかった場合、そのプロセスは遅れたままになります。それをシェルのジョブ番号に関連付ける必要はありません。
端末にアクセスしようとしたが、端末が存在しなくなった場合でも、プロセスは停止する可能性があります。それは、プログラムが存在しない端末にどのように反応するかによって異なります。
ジョブに複数のプロセス(パイプラインなど)が含まれている場合、これらすべてのプロセスは1つにまとめられますプロセスグループ。プロセスグループは、複数の関連プロセスで構成されるシェルジョブの概念を正確に捉えるために発明されました。プロセスグループIDを表示することにより、プロセスグループごとにグループ化されたプロセスを表示できます(PGID-通常、グループ内の最初のプロセスのプロセスID)。 Linuxでのps l
またはps -o pid,pgid,tty,etime,comm
のようなものを移植可能にします。
kill
に負の引数を渡すことにより、グループ内のすべてのプロセスを強制終了できます。たとえば、強制終了するパイプラインのPGIDが1234であると判断した場合は、次のコマンドで強制終了できます。
kill -TERM -1234
一般的にはまだ動作しますが、忘れてしまった、または気が変わった場合はNohupを使用してください。
mike@mike-laptop4:~$ sleep 500
^Z
[1]+ Stopped sleep 500
mike@mike-laptop4:~$ bg
[1]+ sleep 500 &
mike@mike-laptop4:~$ jobs
[1]+ Running sleep 500 &
mike@mike-laptop4:~$ disown %1
mike@mike-laptop4:~$ jobs
mike@mike-laptop4:~$