ruby系统命令检查退出代码

时间:2013-09-10 20:22:07

标签: ruby command exit exit-code

我在ruby中有一堆系统调用,如下所示,我想同时检查它们的退出代码,以便在该命令失败时我的脚本退出。

system("VBoxManage createvm --name test1")
system("ruby test.rb")

我想要像

这样的东西

system("VBoxManage createvm --name test1", 0)< - 其中第二个参数检查退出代码并确认系统调用成功,如果没有,则会引发错误或执行某种操作。

这可能吗?

我已经尝试了一些与此无关的内容,但也无效。

system("ruby test.rb")
system("echo $?")

`ruby test.rb`
exit_code = `echo $?`
if exit_code != 0
  raise 'Exit code is not zero'
end

6 个答案:

答案 0 :(得分:154)

来自documentation

  如果命令给出零退出状态,则

系统返回truefalse   非零退出状态。如果命令执行失败,则返回nil

system("unknown command")     #=> nil
system("echo foo")            #=> true
system("echo foo | grep bar") #=> false

此外

  

$?中有错误状态。

system("VBoxManage createvm --invalid-option")

$?             #=> #<Process::Status: pid 9926 exit 2>
$?.exitstatus  #=> 2

答案 1 :(得分:31)

对我来说,我更喜欢使用``来调用shell命令并检查$?获得流程状态。 $?是一个进程状态对象,您可以从该对象获取命令的进程信息,包括:状态代码,执行状态,pid等。

$的一些有用方法?对象:

   $?.exitstatus => return error code    
   $?.success? => return true if error code is 0, otherwise false
   $?.pid => created process pid

答案 2 :(得分:23)

如果命令具有非零退出代码,则

system返回false;如果没有命令,则返回nil

因此

system( "foo" ) or exit

system( "foo" ) or raise "Something went wrong with foo"

应该有效,并且相当简洁。

答案 3 :(得分:6)

您没有捕获system调用的结果,这是返回结果代码的位置:

exit_code = system("ruby test.rb")

记住每个system调用或等效函数(包括反引号方法)会生成一个新shell,因此无法捕获先前shell环境的结果。在这种情况下,如果一切顺利,exit_codetrue,否则为nil

popen3命令提供更多低级细节。

答案 4 :(得分:4)

执行此操作的一种方法是使用and&&链接它们:

system("VBoxManage createvm --name test1") and system("ruby test.rb")

如果第一个呼叫失败,则不会运行第二个呼叫。

您可以将它们包裹在if ()中,以便为您提供流量控制:

if (
  system("VBoxManage createvm --name test1") && 
  system("ruby test.rb")
) 
  # do something
else
  # do something with $?
end

答案 5 :(得分:0)

<块引用>

我想要类似的东西

system("VBoxManage createvm --name test1", 0) <-- 其中第二个参数检查退出代码并确认该系统调用成功,否则,它将引发错误或执行类似操作。

您可以将 exception: true 添加到您的 system 调用以在非 0 退出代码上引发错误。

例如,考虑这个围绕 system 打印命令的小包装器(类似于 bash -x,如果存在非 0 退出代码(如 bash -e)则失败并返回实际退出代码:

def sys(cmd, *args, **kwargs)
  puts("\e[1m\e[33m#{cmd} #{args}\e[0m\e[22m")
  system(cmd, *args, exception: true, **kwargs)
  return $?.exitstatus
end

被称为:sys("hg", "update") 如果要调用对退出代码使用不同约定的程序,可以禁止引发异常:

sys("robocopy", src, dst, "/COPYALL", "/E", "/R:0", "/DCOPY:T", exception: false)

您还可以抑制嘈杂程序的 stdout 和 stderr:

sys("hg", "update", "default", :out => File::NULL, :err => File::NULL)