2

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

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

将指定的命令生成为子进程,阻塞并验证子进程是否成功终止(返回零)。如果不是,它会抛出异常。check_output做同样的事情,除了它捕获子进程的标准输出并将其作为字节字符串返回。

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

和 的惯用 Ruby 等价物是check_call什么check_output我知道$?提供进程返回值的全局变量,但这会很尴尬——出现异常的关键在于您不必手动检查错误代码。在 Ruby 中生成子进程的方法有很多,但我没有看到任何提供此功能的方法。

4

3 回答 3

1

check_call这是我拼凑起来的一个简单方法,这似乎有效。

def check_call(*cmd, **kw)
  _, status = Process.waitpid2 Kernel.spawn(*cmd, **kw)
  raise "Command #{cmd} #{status}" unless status.success?
end
于 2014-10-22T19:00:01.967 回答
0

POpen4 gem取代了基本/内置方法。而shell-executor gem 提供了更多的功能。

于 2013-05-21T20:41:00.283 回答
0

很难说 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

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

此外,Pythone.message将是默认消息或基于返回码生成的东西,而 Rubye.message将是孩子的stderr.

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

于 2013-05-21T20:42:35.347 回答