2

私の Ruby スクリプトは一時ファイルを作成し、潜在的に長時間実行される外部プロセスを生成します。スクリプトの終了方法に関係なく、スクリプトの終了後にどちらも存在し続けることはできません。

次の行で問題が解決すると思いました。

stderr = File.open(Tempfile.new(__FILE__),'w')
trap("EXIT") { FileUtils.rm_f stderr.path }
pid = spawn("dd", *ARGV, STDERR => stderr )
trap("EXIT") { FileUtils.rm_f stderr.path; Process.kill pid }

これらは、次の bash コードを書き直したものであると思われますが、これは正常に動作するようです。

dd_output=`mktemp`
trap "rm -f $dd_output" EXIT
dd "$@" 2>| $dd_output & pid=$!
trap "rm -f $dd_output; kill $pid" EXIT

しかし、そうではありません。後で例外が発生した場合、生成されたプロセスは終了しません。

誰かが私が間違っていることを教えてもらえますか?

編集:トラップは機能します。上記のコードには複数の欠陥があります。

  1. Tempfile は自動的に処理されます。トラップ ハンドラで既に削除されている可能性があり、FileUtils.rm_f で別のエラーが発生して防止される可能性があります。
  2. Process.kill にはシグナルが必要です -- Process.kill "TERM"、pid (または "KILL")。発生したエラーは、Process.kill の誤った呼び出しのエラーを隠していました。

固定コード:

 stderr = Tempfile.new(__FILE__)
 pid = spawn("dd", *ARGV, STDERR => stderr )
 trap("EXIT") { Process.kill "TERM", pid }

Ensureも動作します。

4

1 に答える 1