2013-05-21 3 views
1

Python предоставляет две удобные функции для вызова подпроцессов, которые могут быть сбойными, subprocess.check_call и subprocess.check_output. В основном,Ruby-эквивалент подпроцесса Python.check_call/check_output

subprocess.check_call(['command', 'arg1', ...]) 

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

Это удобно, потому что это одно выражение Python (вам не нужно настраивать и управлять подпроцессом по нескольким строкам кода), и нет никакого риска забыть проверить возвращаемое значение.

Каковы идиоматические эквиваленты Ruby для check_call и check_output? Мне известно, что глобальное значение $? дает возвращаемое значение процесса, но это было бы неудобно - точка исключения состоит в том, что вам не нужно вручную проверять коды ошибок. There are numerous ways to spawn a subprocess in Ruby, но я не вижу таких, которые предоставляют эту функцию.

ответ

0

Основные/встроенные методы вытесняются драгоценным камнем POpen4. И драгоценный камень shell-executor обеспечивает дополнительную удивительность.

1

Трудно сказать, что является самым идиоматическим решением в Ruby ... но тот, который ближе всего к Python, вероятно, Shell.execute! от shell-executer.

Из примера на странице Документах

begin 
    Shell.execute!('ls /not_existing') 
rescue RuntimeError => e 
    print e.message 
end 

Сравните:

try: 
    subprocess.check_call('ls /not_existing', shell=True) 
except Exception as e: 
    print e.message 

Наиболее заметным отличием является то, что эквивалентно рубин не есть способ сделать shell=False (и возьмите args как список), который Python имеет не только, но и по умолчанию.

Кроме того, в Python e.message будет сообщение по умолчанию или что-то генерируется на основании кода возврата, в то время как Руби e.message будет ребенок stderr.

Если вы хотите сделать shell=False, насколько я знаю, вам придется написать свою собственную обертку вокруг чего-то более низкого уровня; все обертки Ruby, о которых я знаю (shell-executer, Popen4, [open4] [4]) являются обертками вокруг или эмуляторами функций POSIX popen.

1

Вот простой check_call Я выбросил вместе, и это, похоже, сработает.

def check_call(*cmd, **kw) 
    _, status = Process.waitpid2 Kernel.spawn(*cmd, **kw) 
    raise "Command #{cmd} #{status}" unless status.success? 
end 
Смежные вопросы