2010-02-08 2 views
4

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

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

set -o errexit 

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

ответ

7

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

Что-то вроде:

old_sys = system 

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

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

+2

Да, это было то, о чем я думал, когда говорил:« Не будет слишком сложно писать », но это похоже на то, что нужно было решить уже, знаете ли? Спасибо за пример. –

+1

Хотя, вы бы хотели «поднять», а не «бросать» –

+0

@glenn хороший улов, исправленный. – user269044

6

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

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

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

+6

Почему вы используете 'to_s' для сравнения со строкой' 0'? 'if $? == 0' –

+0

Я бы сказал, что даже 'if $ ?. zero?' – Nakilon

+0

@Nakilon '' '$ ?. zero?' '' Raise NoMethodError –

6

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

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

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

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

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

Ссылка: От рубинового 2.0 док для system (хотя верно и 1.8.7, а):

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

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

+0

Интересно, мне это нравится. Не могли бы вы добавить ссылку на свою ссылку (часть документов Ruby, где вы ее нашли)? –

Смежные вопросы