在ruby脚本之后清理 - 捕获信号

时间:2015-03-02 22:21:34

标签: ruby bash error-handling signals bash-trap

我的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的错误调用的错误。
  3. 固定代码:

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

    Ensure也有效。

1 个答案:

答案 0 :(得分:2)

我认为确保可以在这里帮助您,它将始终执行内部代码。它类似于Java的最终

stderr = Tempfile.new(__FILE__)

begin
  pid = spawn("dd", *ARGV, STDERR => stderr )
ensure
  FileUtils.rm_f stderr.path
  Process.kill pid
end

如果没有做到这一点,您可以尝试添加 at_exit 处理程序。