Вызвать исключение при сбое команды оболочки?
Я пишу некоторые скрипты в 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