【问题标题】:How to get Ruby script to fail when shelled-out command returns with non-zero exit code?当带壳命令返回非零退出代码时,如何让 Ruby 脚本失败?
【发布时间】:2015-09-05 11:15:01
【问题描述】:

在Ruby脚本中,有various ways可以调用系统命令/命令行

  1. 反引号:`command arg1 arg2`
  2. 分隔形式,例如%x(command arg1 arg2)(其他分隔符可用)
  3. Kernel#system 方法:system('command arg1 arg2')
  4. Kernel#exec 方法:exec('command arg1 arg2')

如果我希望 Ruby 脚本在调用命令失败(退出代码非零)时失败(有异常),我可以检查特殊变量 $? 中前两个变体的退出代码:

`command arg1 arg2`
fail unless $? == 0

%x,command arg1 arg2,
fail unless $? == 0

如果我可以将命令的标准输出转到 Ruby 脚本的标准输出(我也可以),我可以使用变体 3 并检查其返回值:

unless system('command arg1 arg2')
  fail
end

如果我不关心挽救异常的能力,也不关心未挽救异常的堆栈跟踪打印行为,我当然可以使用exit(1) 或在前两个变体中使用exit($?) 代替fail

如果进一步执行命令是 Ruby 脚本应该做的最后一件事,即使命令成功(退出代码 0),我也可以使用第四个变体:

exec('command arg1 arg2')

这将用调用命令创建的新进程替换 Ruby 进程,但是对于 Ruby 脚本的调用者的效果将是相同的:如果调用的命令导致非零退出代码,他会看到一个非零退出代码。 - 零退出代码。

我非常喜欢第四个变体的简洁性,但是如果执行命令不是最后要做的事情,以防万一它成功,我很遗憾不能使用它。相比之下,其他变体的有条件的 failexit 调用看起来非常不干净,而且在我的一个用例中,往往违反了单一抽象级别和单一职责原则。

我当然可以很容易地为前三种方法中的任何一种编写一个包装函数,以使其用法看起来一样简洁,但是由于这似乎是一种基本的操作方式,我想知道 Ruby 是否已经有了类似的东西内置 ...无论是我可以使用的实用程序函数而不是我自己的包装器,还是一种改变一个或多个命令调用方法的行为以导致错误或非命令失败时零退出,类似于's 和's option to set -e

【问题讨论】:

    标签: sh bash ruby command-line-interface


    【解决方案1】:

    据我所知,没有内置的方法可以做到这一点,但你几乎可以通过一点元编程魔法获得你想要的行为

    def set_exit enable
      if enable
        define_method :system do |*args|
          Kernel.system *args
          exit $?.exitstatus unless $?.success?
        end
      else
        define_method :system, Kernel.instance_method(:system)
      end
    end
    
    set_exit true
    # ...
    # any failed system calls here will cause your script to exit
    # ...
    set_exit false
    # now system is back to normal
    

    这可以通过将system 重新定义为Object 来实现,同时在需要内置行为时显式使用Kernel.system

    【讨论】:

    • 不错。由于backquotes use Kernel#`,我想这种方法也适用于他们。
    • 哇,我不知道这实际上是一种方法!是的,如果你用:` 代替:system,它似乎工作得很好
    猜你喜欢
    • 1970-01-01
    • 2016-11-30
    • 2020-10-28
    • 1970-01-01
    • 2019-02-28
    • 2020-06-27
    • 2020-12-18
    • 2021-08-23
    • 2019-12-03
    相关资源
    最近更新 更多