我正在用Ruby编写一些脚本,我需要通过shell命令与一些非Ruby代码进行交互。我知道Ruby中至少有6 different ways个执行shell命令,不幸的是,当shell命令失败时,这些命令似乎都没有停止执行。
基本上,我正在寻找与以下内容完全相同的东西:
set -o errexit
...在Bash脚本中。理想情况下,当命令失败时(即,通过检查非零返回值),解决方案将引发异常,可能使用stderr作为消息。这不会太难写,但似乎这应该存在。我有没有找到一个选项?
答案 0 :(得分:9)
最简单的方法是创建一个新函数(或重新定义现有函数)来调用system()并检查错误代码。
类似的东西:
old_sys = system
def system(...)
old_system(...)
if $? != 0 then raise :some_exception
end
这应该做你想要的。
答案 1 :(得分:7)
您可以使用ruby的一个特殊变量。 $? (类似于相同的shell脚本var)。
`ls`
if $?.to_s == "0"
# Ok to go
else
# Not ok
end
如果一切正常,几乎每个程序都会将此var设置为0.
答案 2 :(得分:7)
稍微简单一点:您不需要检查$?
w / system
,并且由于您运行的命令将输出到stderr
本身,您通常只能非零 - 退出而不是用丑陋的堆栈跟踪引发异常:
system("<command>") || exit(1)
所以你可以更进一步,做到:
(system("<command 1>") &&
system("<command 2>") &&
system("<command 3>")) || exit(1)
......会因错误而短路并失败(除了难以阅读之外)。
参考:来自{2.0}的Ruby 2.0 doc(尽管也是1.8.7):
如果命令退出状态为零,系统返回
system
,非零退出状态为true
。
http://www.ruby-doc.org/core-2.0.0/Kernel.html#method-i-system
答案 3 :(得分:2)
Ruby 2.6 adds an exception:
argument:
system('ctat nonexistent.txt', exception: true) # Errno::ENOENT (No such file or directory - ctat)