If you wish to issue pipe two commands together in bash then it is easy.
ls /bin | grep grep
generates
bzegrep
bzfgrep
bzgrep
egrep
fgrep
grep
zegrep
zfgrep
zgrep
but how to do this neatly in IRB
How about like
require './shell.rb'
Sh.ls("/bin").grep("grep")
using the library
module Sh
class Command
def initialize(cmd, *args)
@cmd = cmd
@args = args
@io = nil
end
def inspect
to_s
end
def to_str
to_s
end
def to_s
call
str = @io.read
@io.close
str
end
def | other
call
other.call(@io)
end
def method_missing(name, *args)
self | Command.new(name, *args)
end
def call (io=nil)
# The @io object can only be assigned
# once
return self if @io
command = @cmd.to_s + " " + @args.join(" ")
if io
# We need a new process
# and a pipe to connect the
# this command to the previous
# command in the chain.
rd, wr = IO.pipe
if fork
# Parent
wr.close
else
# Child
rd.close
begin
# Reconnect the STDIN of the
# new process to the io parameter
$stdin.reopen(io)
IO.popen command do |f|
while txt = f.read(4096)
wr.write txt
end
end
rescue Errno::EPIPE
# Ignore the broken pipe
# cause the other process
# has thrown away the pipe
# earlier than we used outs
ensure
wr.close
end
exit
end
@io = rd
else
# This command is executed standalone.
@io = IO.popen command
end
self
end
end
def self.method_missing (name, *args)
Command.new(name, *args)
end
end