My ruby script creates a tempfile and spawns an potentially long-running external process. Neither may continue to exist after the script ends, no matter the way in which the script terminates.
I thought the following lines would take care of things:
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 }
they're supposed to be a rewrite of the following bash code, which seems to work fine,
dd_output=`mktemp`
trap "rm -f $dd_output" EXIT
dd "$@" 2>| $dd_output & pid=$!
trap "rm -f $dd_output; kill $pid" EXIT
but they don't. If an exception is raised later on, the spawned process doesn't die, otherwise it does.
Could anyone tell me what I'm doing wrong?
Edit: Traps do work. The above code has multiple blemishes:
- Tempfile takes car of itself -- it is likely to already have been deleted in the trap handler, which may cause FileUtils.rm_f to raise another error, preventing.
- Process.kill needs a signal -- Process.kill "TERM", pid (or "KILL"). The raised error shadowed the error for my faulty invocation of Process.kill.
Fixed code:
stderr = Tempfile.new(__FILE__)
pid = spawn("dd", *ARGV, STDERR => stderr )
trap("EXIT") { Process.kill "TERM", pid }
Ensure
works too.