Ruby相当于Python的subprocess.check_call / check_output

时间:2013-05-21 19:50:06

标签: python ruby process subprocess pipe

Python提供了两个方便的函数来调用可能失败的子进程subprocess.check_callsubprocess.check_output。基本上,

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

将指定的命令作为子进程生成块,并且验证子进程是否成功终止(返回零)。如果没有,它会抛出异常。 check_output执行相同的操作,除了它捕获子进程的stdout并将其作为字节串返回。

这很方便,因为它是一个单独的Python表达式(您不必在几行代码上设置和控制子进程),并且不存在忘记检查返回值的风险。

check_callcheck_output的惯用Ruby等价物是什么?我知道$?全局提供了进程的返回值,但是尴尬 - 有例外的一点是你不必手动检查错误代码。 There are numerous ways to spawn a subprocess in Ruby,但我没有看到任何提供此功能的内容。

3 个答案:

答案 0 :(得分:1)

很难说Ruby中最惯用的解决方案是什么......但是最接近Python的那个可能来自shell-executer Shell.execute!

从文档页面上的示例:

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

这里最显着的区别是Ruby等价物没有办法shell=False(并将args作为列表),Python不仅具有,而且默认为。

此外,Python的e.message将是默认消息或基于返回代码生成的内容,而Ruby的e.message将是孩子的stderr

如果你想做shell=False,据我所知,你必须在较低级别的东西周围编写自己的包装器;我所知道的所有Ruby包装器(shell-executerPopen4,[open4] [4]都是POSIX popen函数的包装器或模拟器。

答案 1 :(得分:1)

这是一个简单的check_call我把它放在一起,这似乎有效。

def check_call(*cmd, **kw)
  _, status = Process.waitpid2 Kernel.spawn(*cmd, **kw)
  raise "Command #{cmd} #{status}" unless status.success?
end

答案 2 :(得分:0)

基本/内置方法被POpen4 gem取代。 shell-executor宝石提供了进一步的精彩。