我知道有足够的Ruby是危险的,所以我正在编写一堆构建自动化脚本作为Rake任务,主要是通过API文档中的示例来处理。
我正在编写一堆构建命令,其代码如下:
results = {}
schemes.each { |scheme|
command = "xcodebuild", "-scheme", scheme
if options.configuration
command.push "-configuration", options.configuration
end
command.push "archive"
sh *command do |ok, res|
results[scheme] = ok
end
}
这样可以正常工作,但会将 lot 的输出转储到控制台,这样会妨碍它。因此,我希望通过xcpretty来管理这些内容以重新格式化。
如果我实际上从我的终端运行命令,它可以正常工作:
xcodebuild -scheme Foo -configuration Release archive | xcpretty
但是如果我修改Rake任务只是将这些部分附加到命令数组的末尾,sh
认为它们是xcodebuild
的参数。
command.push "archive", "|", "xcpretty"
我已经看到了一些使用sh
的示例,其中包含字符串形式的管道,但不是数组形式。由于命令的性质,我正在构建可选参数,带空格和其他字符的参数 - 数组形式要处理得更清晰。但使用它时是否有办法包括输出管道?
答案 0 :(得分:3)
一个好的解决方案是使用Open3,这是Ruby的标准部分,它有许多用于打开流程和安排管道的实用工具。
这是一个对我有用的例子:
require 'open3'
Open3.pipeline(['ls', '-l'], ['grep', 'z'])
运行此命令时,管道中最后一个命令的标准输出管道将连接到Ruby进程的预先存在的标准输出管道。这意味着您可以在生成时立即看到任何输出,而不是等待进程结束。这种方法的另一个好处是它不会产生shell;它只是直接产生过程。
另一种选择是在将参数传递给sh
之前简单地使用Array#join将参数与空格连接在一起。你只需要注意你的参数可能在其中有空格的可能性,如果是这样,那么你必须正确引用或转义它们。此方法将生成一个shell来处理您的命令,它还应该为长时间运行的进程提供即时输出。