ruby系统命令检查退出代码

use*_*318 102 ruby command exit-code exit

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

system("VBoxManage createvm --name test1")
system("ruby test.rb")
Run Code Online (Sandbox Code Playgroud)

我想要类似的东西

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

这有可能吗?

我已经尝试过这方面的事情,但也没有用.

system("ruby test.rb")
system("echo $?")
Run Code Online (Sandbox Code Playgroud)

要么

`ruby test.rb`
exit_code = `echo $?`
if exit_code != 0
  raise 'Exit code is not zero'
end
Run Code Online (Sandbox Code Playgroud)

Ste*_*fan 159

文档:

true如果命令给出零退出状态,则系统返回false非零退出状态.nil命令执行失败时返回.

system("unknown command")     #=> nil
system("echo foo")            #=> true
system("echo foo | grep bar") #=> false
Run Code Online (Sandbox Code Playgroud)

此外

可以使用错误状态$?.

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

$?             #=> #<Process::Status: pid 9926 exit 2>
$?.exitstatus  #=> 2
Run Code Online (Sandbox Code Playgroud)

  • 以及如何将其输出(不是退出代码)捕获到变量? (2认同)

Hou*_*eng 37

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

$的一些有用的方法?宾语:

   $?.exitstatus => return error code    
   $?.success? => return true if error code is 0, otherwise false
   $?.pid => created process pid
Run Code Online (Sandbox Code Playgroud)

  • 在 Rubocop 的帮助下,我发现 `$?` 的可读别名是 `$CHILD_STATUS` (4认同)

Nei*_*ter 23

system返回false,如果命令具有非零退出代码,或者nil如果没有命令.

因此

system( "foo" ) or exit
Run Code Online (Sandbox Code Playgroud)

要么

system( "foo" ) or raise "Something went wrong with foo"
Run Code Online (Sandbox Code Playgroud)

应该工作,并且相当简洁.


tad*_*man 6

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

exit_code = system("ruby test.rb")
Run Code Online (Sandbox Code Playgroud)

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

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

  • [`Open3.capture3`](http://www.ruby-doc.org/stdlib-2.0.0/libdoc/open3/rdoc/Open3.html#method-c-capture3)是一种特别容易使用的方法这种任务. (2认同)
  • exit_code可能不是它的最佳名称 (2认同)

the*_*Man 6

一种方法是使用and或链接它们&&

system("VBoxManage createvm --name test1") and system("ruby test.rb")
Run Code Online (Sandbox Code Playgroud)

如果第一个调用失败,则第二个调用将不会运行。

您可以将它们包装在中,if ()以进行一些流量控制:

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