在 ruby 脚本之后清理——捕获信号
Cleaning up after a ruby script -- trapping signals
我的 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
也有效。
我想ensure也许能帮到你,它会一直执行里面的代码。它类似于 Java 的 finally。
stderr = Tempfile.new(__FILE__)
begin
pid = spawn("dd", *ARGV, STDERR => stderr )
ensure
FileUtils.rm_f stderr.path
Process.kill pid
end
如果这不起作用,您可以尝试添加 at_exit 处理程序。
我的 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
也有效。
我想ensure也许能帮到你,它会一直执行里面的代码。它类似于 Java 的 finally。
stderr = Tempfile.new(__FILE__)
begin
pid = spawn("dd", *ARGV, STDERR => stderr )
ensure
FileUtils.rm_f stderr.path
Process.kill pid
end
如果这不起作用,您可以尝试添加 at_exit 处理程序。