3

rubyスクリプトでは、次のように、それぞれがシェルマネージャーオブジェクトによって管理される仮想シェルをさらに開始します。

@shell = PTY.spawn 'env PS1="\w>" TERM=dumb COLUMNS=63 LINES=21 sh -i'

後で、このインスタンスを破棄し、関連するシェルプロセスを強制終了したいと思います。悲しいことに、私は何も正しく動作させることができません。動作する確率の順に、私が試したことは次のとおりです。

  • 何もありません。つまり、管理オブジェクトが破棄されたときにシェルプロシージャが閉じられることを期待していません。
  • killコマンドを使用してシェルで実行されているすべてのプロセスを強制終了し(これは機能します)、次に。を使用してシェル自体を強制終了しsystem("kill #{@shell[2]")ます。これは効果がありません。
  • 上記で-9を使用します。これにより、シェルプロセスが機能しなくなります。

rubyプログラムが終了するとすべてのシェルが閉じられますが、プログラムを実行したままシェルを強制終了したいと思います。誰かが以前にこのようなものに遭遇しましたか?

4

1 に答える 1

5

問題はゾンビ。はい、そうです。

すべての Unix スタイルのカーネルは、誰かがそれを待つまでプロセスを放置します。(これは、PID、終了ステータス、およびその他の要素を追跡するためです。) それらはゾンビと呼ばれ、ps(1) リストに Z 状態があります。彼らはすでに死んでいるので、殺すことはできません。あなたが彼らを待っているとき、彼らは去ります。

したがって、@shellオブジェクトをクリーンアップする方法は次のとおりです。

@shell[0].close
@shell[1].close
begin
  Process.wait @shell[2]
rescue PTY::ChildExited
end

例外を広範囲にキャッチする上位層があるかどうかによっては、レスキュー ブロックが必要ない場合があります。(ため息、私のirbのように。)

ちなみに、Ruby プログラムが終了したときにプロセスが最終的に消滅したのは、ゾンビも孤立 (親プロセスなし) になり、シェルまたは init(8) のいずれかが最終的にすべての孤立を待機するためです。

于 2011-06-10T19:57:30.050 に答える