Ruby的at_exit和退出状态

17

我能否在 at_exit 块中确定自身进程的退出状态?

at_exit do
  if this_process_status.success?
    print 'Success'
  else
    print 'Failure'
  end
end
2个回答

23

借鉴自tadman

at_exit do
  if $!.nil? || ($!.is_a?(SystemExit) && $!.success?)
    print 'success'
  else
    code = $!.is_a?(SystemExit) ? $!.status : 1
    print "failure with code #{code}"
  end
end

或者不使用 Perl 语法的方式:

require 'English'

at_exit do
  if $ERROR_INFO.nil? || ($ERROR_INFO.is_a?(SystemExit) && $ERROR_INFO.success?)
    print 'success'
  else
    code = $ERROR_INFO.is_a?(SystemExit) ? $ERROR_INFO.status : 1
    print "failure with code #{code}"
  end
end

2
我个人的意见是把“检查”交给tadman而不是你自己。/耸肩。 - Reed Debaets
1
我认为应该检查最完整的答案。对于寻找答案的其他用户来说,检查是最有用的,而且无论我和tadman选择哪个答案进行检查,都不会对我们产生任何影响。 - tig
我认为对于小脚本来说,使用 at_exit 是可以的。但对于大型应用程序,你应该在预期的退出点使用 exit(或调用自己的方法来处理退出),并明确地处理错误、异常和信号。 - Kelvin
($!.is_a?(SystemExit) && $!.success?) 是什么? - Nakilon
1
@Nakilon 检查退出是由于显式调用 exit(或 raise SystemExit)并且退出代码成功(等于0)引起的。 - tig
显示剩余2条评论

20
尽管相关文档非常简略,但 $! 被设置为最后一个发生的异常,在 exit() 调用后它将成为 SystemExit 异常。将这两个结合起来,你可以得到以下代码:
at_exit do
  if ($!.success?)
    print 'Success'
  else
    print 'Failure'
  end
end

只有在调用exit时才会出现这种情况。 当$!为空或为SystemExit时,我肯定可以进行测试,这在成功时返回true。 但是,是否可能获取Process :: Status对象,或者它不适用于顶级进程? - tig
使用您的想法,我得到了答案并发布了它,但我不知道哪个答案更好标记 - 您的还是我的? - tig
无论对你来说哪种方法都可以。我不知道你可以“回答”自己的问题,但好吧。 - tadman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接