How to get Ruby script to fail when shelled-out command returns with non-zero exit code?
在Ruby脚本中,有多种方法可以调用系统命令/命令行
如果我希望ruby脚本在被调用的命令失败(使用非零退出代码)时失败(有例外),我可以检查特殊变量
1 2 | `command arg1 arg2` fail unless $? == 0 |
或
1 2 | %x,command arg1 arg2, fail unless $? == 0 |
如果命令的标准输出指向ruby脚本的标准输出(我也可以),那么我可以使用变量3并检查其返回值:
1 2 3 | unless system('command arg1 arg2') fail end |
如果我不关心挽救异常的能力,也不关心未提示异常的stacktrace打印行为,我当然可以使用
如果命令的进一步执行是Ruby脚本应该做的最后一件事,即使命令成功(退出代码
1 | exec('command arg1 arg2') |
这将用调用命令创建的新进程替换Ruby进程,但Ruby脚本调用方的效果将是相同的:如果被调用的命令导致非零退出代码,他将看到一个非零退出代码。
我非常喜欢第四个变量的简洁性,但是如果执行命令不是万一成功的最后一件事,那么不幸的是我不能使用它。相比之下,其他变体的有条件的
当然,我可以很容易地为前三种方法中的任何一种编写一个包装函数,使它们的用法看起来同样简洁,但由于这似乎是一种基本的操作方式,我想知道Ruby是否已经有了类似的内置功能…无论是我可以使用的实用函数,而不是我自己的包装器,还是在命令失败时改变一个或多个命令调用方法的行为以导致错误或非零退出的机制,类似于sh和bash对EDOCX1的选项(13)。
据我所知,没有内置的方法可以做到这一点,但是你几乎可以用一点元编程的魔力得到你想要的行为。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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 |
这是通过为