孤立プロセスで端末エミュレータが閉じられているかどうかを検出する方法

孤立プロセスで端末エミュレータが閉じられているかどうかを検出する方法

デーモンプロセスを作成した後に孤立するコマンドラインユーティリティがあります。ターミナルエミュレータでデーモンプロセスを終了するにはどうすればよいですか?

答え1

プロセスがデーモンになってSIGHUPを無視すると(または独自のセッションリーダーになり、自分のプロセスグループに属する可能性が高くなります)。送るSIGHUP)、端末エミュレータが閉じたときに終了する唯一の方法は、対応するPIDを記録し、致命的な信号を送信することです。

# pid=$(</var/run/some-daemon.pid)
# trap "kill $pid" EXIT

これはbashまたは互換性のあるシェルを使用すると仮定します。デーモンのPIDを取得する方法はさまざまですが、ほとんどのデーモンはPIDをファイルに書き込みます。本当の魔法はtrap命令である。


thrigが指摘したように、このテクニックはデーモンがPIDファイルに書き込み、ユーザーが通常(exit、^ Dなどを使用して)シェルを終了すると仮定します。この技術は脆弱ですが、簡単です。

答え2

プロセスデーモンの目的は次のとおりです。いいえ親によって異なります。

任意のpidに依存するには、pidfdを有効にできます。pidfd_open、サンプルコードがありますが、epoll好むかもしれませんpoll

したがって、デーモン自体が実行される前に、ユーティリティは興味を持っているいくつかのプロセスを見つけようとします。おそらく、そのプロセスが明らかにシェルによって開始され、シェルの親に依存していることを確認し、そうでない場合はpid cmdlineオプションを使用することもできます。私にとって、祖父母はターミナルエミュレータではなく、私のtmuxサーバーになります。何が正しいかは明確ではなく、状況によっては、おそらく純粋に好みに応じて変わることがあります。

答え3

デーモンはデュアルフォークを実行したり、PIDファイルをサポートしなかったり、プロセスリストから名前をランダムに変更したりできます。デーモンの場合しないでください以前の状況では、$!シェル変数で追跡したり、ファイルが存在したり、内容が正しいことを祈るcatことができます(デーモンがクラッシュして他のものが同時にそのPIDを取得した場合、PIDは正しくありません)。 )またはpkill(1)シェルトラップEXITでプロセスを見つけて終了する方法。 (シェルを別のプログラムに置き換えると、シェルトラップが実行されない可能性がありEXITますので、exec some-other-program注意してください。)この言葉は信じられないものではありませんか?その理由は信頼性が悪いからです。

デーモンにはフォアグラウンドで実行できるオプションがあります。この場合、次のように起動でき、your-daemon --with-the-foreground-flag &必要に応じてデーモンの出力をリダイレクトできます。この場合、SIGHUP親シェルプロセスが終了したらデーモンに適用する必要があります。 (しかし、exec他のプログラムのシェルならばそうではありません。)

Linuxを使用している場合、人々はターミナル、デーモン、その他すべてをカスタムcgroupに入れ、セッションの終わりにグループ全体を終了できます。systemdがこれを行う際に問題が発生しました。tmux基本的に。これは、デュアルフォークエスケープ$!、PIDファイルなし、無効なPIDファイル、またはプロセスリストからプロセス名を推測するよりも信頼性が高いです。また、cgroupはシェルがexec別のプロセスになると気にしません。

関連情報