ruby系统命令检查退出代码

问题描述 投票:0回答:7

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

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

我想要类似的东西

system("VBoxManage createvm --name test1", 0)
<-- where the second parameter checks the exit code and confirms that that system call was successful, and if not, it'll raise an error or do something of that sort.

这可能吗?

我已经尝试过类似的方法,但也不起作用。

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

`ruby test.rb`
exit_code = `echo $?`
if exit_code != 0
  raise 'Exit code is not zero'
end
ruby command exit exit-code
7个回答
187
投票

来自文档

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

true

系统返回
false
,对于
  非零退出状态。如果命令执行失败,则返回 
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
    

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

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

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

33
投票

system

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

因此

system( "foo" ) or exit

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

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


7
投票
您没有捕获

system

 调用的结果,这是返回结果代码的地方:

exit_code = system("ruby test.rb")

记住每个

system

 调用或等效调用(包括反引号方法)都会生成一个新的 shell,因此不可能捕获先前 shell 环境的结果。在这种情况下,如果一切顺利,则 
exit_code
true
,否则为 
nil

popen3

命令提供更多底层细节。
    


6
投票
一种方法是使用

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
投票

Ruby 2.6 添加了在 Kernel#system 中引发异常的选项:

system("command", exception: true)
    

2
投票
我想要类似的东西

system("VBoxManage createvm --name test1", 0)


<-- where the second parameter checks the exit code and confirms that that system call was successful, and if not, it'll raise an error or do something of that sort.

您可以将

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)
    
© www.soinside.com 2019 - 2024. All rights reserved.