Код возврата команды рубиновой системы

У меня есть куча системных вызовов в ruby, таких как следующие, и я хочу проверить их коды выхода одновременно, чтобы мой script вышел, если эта команда завершилась неудачно.

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

Ответ 1

Из документации:

Система

возвращает true, если команда дает нулевой статус выхода, false для non zero статус выхода. Возвращает 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

Ответ 2

system возвращает false, если команда имеет ненулевой код выхода или nil, если команды нет.

Поэтому

system( "foo" ) or exit

или

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

должен работать и быть достаточно кратким.

Ответ 3

Для меня я предпочел использовать `` для вызова команд оболочки и проверки $? для получения статуса процесса. $? является объектом статуса процесса, вы можете получить информацию о процессе процесса от этого объекта, включая: код состояния, статус выполнения, pid и т.д.

Некоторые полезные методы $? Объект:

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

Ответ 4

Вы не записываете результат своего вызова system, в который возвращается возвращаемый код:

exit_code = system("ruby test.rb")

Помните, что каждый вызов system или его эквивалент, который включает метод backtick-method, порождает новую оболочку, поэтому невозможно получить результат предыдущей оболочки. В этом случае exit_code true, если все сработало, nil в противном случае.

Команда popen3 предоставляет более подробные сведения о нижнем уровне.

Ответ 5

Один из способов сделать это - связать их с помощью 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