在Ruby中有没有自动执行shell管道的方法?我正在尝试将以下shell代码转换为Ruby:
a | b | c... > ...
但到目前为止,我找到的唯一解决方案是自己做缓冲区管理(简化的,未经测试的,希望它能理解我的意思):
a = IO.popen('a')
b = IO.popen('b', 'w+')
Thread.new(a, b) { |in, out|
out.write(in.readpartial(4096)) until in.eof?
out.close_write
}
# deal with b.read...
我想我正在寻找的是一种告诉popen使用现有流而不是创建新流的方法?或者,使用IO#merge方法将a的输出连接到b的输入?当过滤器的数量增加时,我目前的方法变得相当笨拙。
我显然知道Kernel#system('a | b')
,但我需要以通用的方式将Ruby过滤器与外部程序过滤器混合在一起。
发布于 2011-01-19 23:17:41
老问题,但由于它是谷歌上的第一个结果之一,下面是答案:http://devver.wordpress.com/2009/10/12/ruby-subprocesses-part_3/ (方法8)
简而言之:
sh = Shell.new
sh.system("a") | sh.system("b") | sh.system("c")
你可以做更复杂的事情,比如
sh.echo(my_string) | sh.system("wc") > "file_path"
xml = (sh.echo(html) | sh.system("tidy", "-q")).to_s
发布于 2015-03-10 22:46:16
使用普通的ruby,spawn
具有重定向选项,您可以使用这些选项将进程与管道连接起来。
1)创建管道
r,w = IO.pipe
2)使用它连接两个衍生的进程
spawn(*%w[echo hello world], out: w)
spawn(*%w[tr a-z A-Z], in: r)
# => HELLO WORLD
当然,您可以将其封装在前面提到的Shell库中的sh.system
中,并创建一个|()方法来进行互连。
标准库的open3模块有一些非常好的工具来处理这类事情,包括创建完整的管道。
发布于 2010-11-21 08:25:08
如果a
、b
和c
是通常从命令行访问的命令,则可以使用:
captured_output = `a | b | c`
Ruby将在子shell中运行这些命令,并捕获STDOUT。
如果出于某种原因需要将输出路由到某个文件,那么也可以将重定向添加到命令中。在这种情况下,STDOUT不会返回给您,但您可以打开该文件并手动处理它:
`a | b | c > captured_output`
File.foreach('captured_output') do |li|
print li
end
它不像使用system
或popen3
提供那么多的控制,但它很方便:
>> sin, sout, serr = Open3.popen3('ls -al | tail -1') #=> [#<IO:fd 4>, #<IO:fd 5>, #<IO:fd 7>, #<Thread:0x00000100bb8798 run>]
>> sout.read #=> "drwxr-xr-x 3 greg staff 102 Nov 2 21:01 python\n"
https://stackoverflow.com/questions/4234119
复制相似问题