csh で nohup がない場合、ssh が終了した後もバックグラウンド ジョブが実行されます。

csh で nohup がない場合、ssh が終了した後もバックグラウンド ジョブが実行されます。

nohupssh でバックグラウンド コマンドを使用する必要性を理解しようとしています。私のシェルは CentOS 上の csh です。

  1. 以下のバックグラウンド コマンドは、ssh が終了した後も実行され続けます。これは、nohupコマンドの前に が付いていた場合にのみ発生すると予想していました。

    どのようなシナリオがnohup必要になるのでしょうか?

     ssh host 'sleep 80 >& /dev/null &'
    
  2. 対話型シェルも試してみましたが、ssh が終了した後もバックグラウンド ジョブの PID はホスト上にまだ存在しています。

     ssh host sleep 80 >& /dev/null & exit
    
  3. kill -HUP PIDまた、ではなく を使用して対話型セッションを終了しようとしましたがexit、ssh が終了した後もバックグラウンド ジョブの PID がホスト上に存在し続けます。

何か間違っているのでしょうか?

答え1

いや背景セッション リーダー (シェル) が終了したとき、またはその制御端末が破棄されたときには、プロセス グループ (ジョブ) はデフォルトでは終了されません。

それが起こるのは、いくつかの特別なケースのみです:

(1)バックグラウンドジョブは停止、その場合、信号ペアが送信さSIGHUPSIGCONTますカーネルSIGHUPシグナルがプロセスによってキャッチまたは無視されない場合、プロセスは終了します。

停止したジョブの定義は、停止したプロセスを含むジョブです。プロセス睡眠nanosleep(2)またはのようなブロッキング システム コールでは、read(2)停止しているとは見なされません。

(2)プロセスは、もは​​や存在しない端末に対して読み取りまたは書き込みを試行し、その試行時にエラーが発生したために(自発的に)終了します。

(3)この仕事は実際には前景仕事。カーネルSIGHUPセッション リーダー/制御プロセス (つまりシェル) が終了すると、フォアグラウンド プロセス グループにシグナルが送信されます。制御プロセスはSIGHUP、制御端末が破棄されるとシグナルを受け取り、通常は終了します。

で始まるコマンドも、&実際には前景ジョブ制御のないシェルから起動されたプロセスグループ(ほとんどのシェルでは、cshではデフォルトですが、スクリプトそしてサブシェル)。

(4)bashまたは のようなシェルを使用していますzsh。これらのシェルは、 でシグナルを受け取ったとき(上記のポイント 3 に従い、シェルが制御プロセスです)、または単に終了したとき (後者は ではデフォルトのみですが、 bash ではデフォルトではなくオプションに従います)、SIGHUPすべてのジョブにシグナルを送信します。SIGHUPzshshopt huponexit

cshシェル(本物か偽物cshtcshそのような行動をとらないbashまたはからzsh。 ではtcsh(実際の ではそうではありません) 、シェルの終了時にコマンドを hup するために、組み込みcshコマンドを使用してコマンドを開始できます。hup

tcsh% hup sleep 3600 &
tcsh% exit
$ pgrep sleep
[nothing]

(5)initシステムは終了したユーザーセッションをクリーンアップするために全力を尽くします。デフォルトの設定では、システムすべてのプロセスに信号を送ります範囲遅延後SIGTERMに が続くので、いずれにしてもその点では役に立ちません。また、systemdのSIGKILLnohup範囲は Unix プロセス セッションと一致しないため、 でコマンドを実行しても、setsid(1)それを回避することはできません。

KillUserProcesses=yes、、KillMode=control-groupおよびオプションKillSignal=SIGTERMをデフォルトから微調整することで、systemd の動作を変更できる可能性がありますSendSIGKILL=yes

関連情報