私の 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
しかし、そうではありません。後で例外が発生した場合、生成されたプロセスは終了しません。
誰かが私が間違っていることを教えてもらえますか?
編集:トラップは機能します。上記のコードには複数の欠陥があります。
- Tempfile は自動的に処理されます。トラップ ハンドラで既に削除されている可能性があり、FileUtils.rm_f で別のエラーが発生して防止される可能性があります。
- 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
も動作します。