Skip to content

Instantly share code, notes, and snippets.

@wycats
Created December 18, 2009 03:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save wycats/259268 to your computer and use it in GitHub Desktop.
Save wycats/259268 to your computer and use it in GitHub Desktop.
class TwoWayPipe
attr_reader :pull, :push
def initialize
@pull, @push = IO.pipe
end
end
class PipeProcess
def self.start(command, last_pipe = TwoWayPipe.new, original_pipe = last_pipe)
new(command, last_pipe, original_pipe)
end
attr_reader :original_pipe
def initialize(command, last_pipe, original_pipe)
@original_pipe = original_pipe
pipe = TwoWayPipe.new
fork do
pipe.push.close
STDOUT.reopen(last_pipe.push)
STDIN.reopen(pipe.pull)
exec command
end
@pipe = pipe
end
def read
@original_pipe.push.close
@original_pipe.pull.read
end
def pipe(command)
self.class.start(command, @pipe, @original_pipe).tap do
@pipe.push.close
end
end
end
class ReversePipeProcess
def initialize(command, last_process = nil)
@command, @last_process = command, last_process
end
def pipe(command)
self.class.new(command, self)
end
def commands
commands = []
commands << @command
commands.concat(@last_process.commands) if @last_process
commands
end
def read
list = commands
first = PipeProcess.start(list.shift)
list.inject(first) {|process, command| process.pipe(command) }.read
end
end
module Kernel
def pipe(command)
ReversePipeProcess.new(command)
end
end
puts pipe("ls").pipe("grep Adium").pipe("grep 'Update 1'").read
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment