ruby系统命令检查退出代码

plicqrtu  于 2023-10-17  发布在  Ruby
关注(0)|答案(7)|浏览(126)

我在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
c86crjj0

c86crjj01#

来自文档:
如果命令给出零退出状态,则系统返回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
qzwqbdag

qzwqbdag2#

对我来说,我更喜欢使用``来调用shell命令并检查$?获取进程状态。$?是一个进程状态对象,你可以从这个对象中获取命令的进程信息,包括:状态代码、执行状态、PID等。
一些有用的方法的$?对象:

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

mcdcgff03#

system返回false,如果命令有非零的退出代码,或者nil,如果没有命令。
因此

system( "foo" ) or exit

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

应该工作,并合理简洁。

xzv2uavs

xzv2uavs4#

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

exit_code = system("ruby test.rb")

请记住,每个system调用或等效调用(包括backtick-method)都会产生一个新的shell,因此不可能捕获前一个shell环境的结果。在这种情况下,如果一切顺利,exit_codetrue,否则是nil
popen3命令提供了更低级别的详细信息。

v64noz0r

v64noz0r5#

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

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

如果第一个调用失败,则不会运行第二个调用。
您可以将它们 Package 在if ()中,以给予一些流控制:

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

rggaifut7#

我想要的是
system("VBoxManage createvm --name test1", 0) <--其中第二个参数检查退出代码并确认系统调用是否成功,如果没有,它将引发错误或执行类似操作。
您可以将exception: true添加到system调用中,以便在非0退出代码时引发错误。
例如,考虑system周围的这个小 Package 器,它打印命令(类似于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)

相关问题