Вызвать исключение при сбое команды оболочки?

Я пишу некоторые скрипты в Ruby, и мне нужно взаимодействовать с некоторым не-Ruby кодом через команды оболочки. Я знаю, что есть по крайней мере 6-разному выполнения команд оболочки из Ruby, к сожалению, ни один из них, похоже, не останавливает выполнение при сбое команды оболочки.

в принципе, я ищу что-то, что делает эквивалент:

set -o errexit

...в сценарии Bash. В идеале решение вызовет исключение при сбое команды (т. е., проверяя ненулевое возвращаемое значение), возможно, с помощью stderr в качестве сообщения. Это было бы не слишком сложно написать, но похоже, что это уже должно существовать. Есть ли вариант, который я просто не нахожу?

3 ответов


самый простой способ-создать новую функцию (или переопределить существующую) для вызова system() и проверки кода ошибки.

что-то типа:

old_sys = system

def system(...)
  old_system(...)
  if $? != 0 then raise :some_exception
end

Это должно делать то, что вы хотите.


вы можете использовать одну из специальных переменных ruby. В $? (аналогично тому же сценарию оболочки var).

`ls`
if $?.to_s == "0"
  # Ok to go
else
  # Not ok
end

почти каждая программа устанавливает этот var в 0, если все прошло хорошо.


немного проще: вам не нужно проверять $? w/system, а с командой ты побежал выводить stderr сам вы обычно можете просто ненулевой выход, а не вызывать исключение с уродливой трассировкой стека:

system("<command>") || exit(1)

таким образом, вы можете сделать еще один шаг и сделать:

(system("<command 1>") &&
  system("<command 2>") &&
  system("<command 3>")) || exit(1)

...что будет короткое замыкание и сбой при ошибке (в дополнение к тому, что трудно читать).

Ref: от Ruby 2.0 doc для system (хотя верно для 1.8.7 как ну):

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

http://www.ruby-doc.org/core-2.0.0/Kernel.html#method-i-system