Open3.popen3
代表Kernel.spawn
,根据命令传入的方式,将命令提供给 shell 或直接提供给操作系统。
commandline : command line string which is passed to the standard shell
cmdname, arg1, ... : command name and one or more arguments (This form does not use the shell. See below for caveats.)
[cmdname, argv0], arg1, ... : command name, argv[0] and zero or more arguments (no shell)
我们可能期望如果我们调用Kernel.spawn("foo")
,它将被传递到 shell(而不是操作系统)。但事实并非如此,文档Kernel.exec
解释原因:
If the string from the first form (exec("command")) follows these simple rules:
* no meta characters
* no shell reserved word and no special built-in
* Ruby invokes the command directly without shell
You can force shell invocation by adding ";" to the string (because ";" is a meta character).
最后一段揭示了解决方案。
require "open3"
stdout, stderr, status = Open3.capture3(command + ";")
case status.exitstatus
when 0
return stdout
when 1, 127
raise MyError, stderr
end