简体   繁体   English

ruby 系统命令检查退出代码

[英]ruby system command check exit code

I have a bunch of system calls in ruby such as the following and I want to check their exit codes simultaneously so that my script exits out if that command fails.我在 ruby​​ 中有一堆系统调用,如下所示,我想同时检查它们的退出代码,以便我的脚本在该命令失败时退出。

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

I want something like我想要类似的东西

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("VBoxManage createvm --name test1", 0) <-- 其中第二个参数检查退出代码并确认该系统调用成功,如果没有,它将引发错误或执行此类操作。

Is that possible at all?这可能吗?

I've tried something along the lines of this and that didn't work either.我已经尝试过类似的方法,但也没有奏效。

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

or或者

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

From the documentation :文档

system returns true if the command gives zero exit status, false for non zero exit status.如果命令给出零退出状态,则系统返回true ,非零退出状态为false Returns nil if command execution fails.如果命令执行失败,则返回nil

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

Furthermore此外

An error status is available in $?错误状态在$? . .

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

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

For me, I preferred use `` to call the shell commands and check $?对我来说,我更喜欢使用 `` 来调用 shell 命令并检查 $? to get process status.获取进程状态。 The $?美元? is a process status object, you can get the command's process information from this object, including: status code, execution status, pid, etc.是一个进程状态对象,可以从这个对象中获取命令的进程信息,包括:状态码、执行状态、pid等。

Some useful methods of the $? $? 的一些有用方法? object:目的:

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

system returns false if the command has an non-zero exit code, or nil if there is no command.如果命令具有非零退出代码,则system返回false如果没有命令,则返回nil

Therefore所以

system( "foo" ) or exit

or要么

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

should work, and are reasonably concise.应该工作,并且相当简洁。

You're not capturing the result of your system call, which is where the result code is returned:您没有捕获system调用的结果,这是返回结果代码的地方:

exit_code = system("ruby test.rb")

Remember each system call or equivalent, which includes the backtick-method, spawns a new shell, so it's not possible to capture the result of a previous shell's environment.请记住,每个system调用或等价物(包括反引号方法)都会产生一个新的 shell,因此不可能捕获先前 shell 环境的结果。 In this case exit_code is true if everything worked out, nil otherwise.在这种情况下,如果一切顺利, exit_codetrue ,否则nil

The popen3 command provides more low-level detail. popen3命令提供了更多的底层细节。

One way to do this is to chain them using and or && :一种方法是使用and&&将它们链接起来:

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

The second call won't be run if the first fails.如果第一个调用失败,则不会运行第二个调用。

You can wrap those in an if () to give you some flow-control:您可以将它们包装在if ()以提供一些流量控制:

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

I want something like我想要类似的东西

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("VBoxManage createvm --name test1", 0) <-- 其中第二个参数检查退出代码并确认该系统调用成功,如果没有,它将引发错误或执行此类操作。

You can add exception: true to your system call to have an error raised on non 0 exit codes.您可以在system调用中添加exception: true以在非 0 退出代码上引发错误。

For example, consider this small wrapper around system which prints the command (similar to bash -x , fails if there's a non 0 exit code (like bash -e ) and returns the actual exit code:例如,考虑这个围绕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

To be called like: sys("hg", "update") If you want to call a program that uses a different convention for exit codes, you can suppress raising the exception:调用方式如下: sys("hg", "update")如果你想调用一个对退出代码使用不同约定的程序,你可以抑制引发异常:

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

You can also suppress stdout and stderr for noisy programs:您还可以抑制嘈杂程序的 stdout 和 stderr:

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

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

system("command", exception: true)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM