Asp Forum
Home
|
Login
|
Register
|
Search
Forums
>
comp.lang.ruby
Chaining external commands using pipes.
Brad Phelan
9/7/2007 6:34:00 AM
I have come up with a little script that works well in IRB for issuing
shell commands and piping them together. For example
require './shell.rb'
io = Sh.ls("/bin").grep("grep")
puts io
generates
bzegrep
bzfgrep
bzgrep
egrep
fgrep
grep
zegrep
zfgrep
zgrep
I am curious as to whether the way I have implemented it is the best
way. It seems kind of clunky to me. I have to spawn a new Ruby process
using fork and then reopen $stdin on the child process and connect it
to the output stream of the previous command. I was hoping to find
a way to get around forking ruby processes to do this. Any
ideas
The source code is below or syntax highlighted here
http://xtargets.com/snippets/pos...
Brad
--------------------------------
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
2 Answers
Konrad Meyer
9/7/2007 6:52:00 AM
0
On Thursday 06 September 2007 11:35:05 pm Brad Phelan wrote:
> I have come up with a little script that works well in IRB for issuing
> shell commands and piping them together. For example
>
> require './shell.rb'
>
> io = Sh.ls("/bin").grep("grep")
> puts io
>
> generates
>
>
> bzegrep
> bzfgrep
> bzgrep
> egrep
> fgrep
> grep
> zegrep
> zfgrep
> zgrep
>
> I am curious as to whether the way I have implemented it is the best
> way. It seems kind of clunky to me. I have to spawn a new Ruby process
> using fork and then reopen $stdin on the child process and connect it
> to the output stream of the previous command. I was hoping to find
> a way to get around forking ruby processes to do this. Any
> ideas
>
> The source code is below or syntax highlighted here
>
http://xtargets.com/snippets/pos...
>
> Brad
>
> --------------------------------
>
> 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
Stdlib shell (require 'shell') does much of that IIRC.
(
http://ruby-doc.org/stdlib/libdoc/shell/rdoc/classes/...
)
--
Konrad Meyer <konrad@tylerc.org>
http://konrad.sobertil...
Brad Phelan
9/7/2007 7:10:00 PM
0
>
> Stdlib shell (require 'shell') does much of that IIRC.
> (
http://ruby-doc.org/stdlib/libdoc/shell/rdoc/classes/...
)
>
Perhaps but there is zero documentation for any of the classes in the
shell library and I don't see anything specific to creating pipes
between processes there.
Brad
Servizio di avviso nuovi messaggi
Ricevi direttamente nella tua mail i nuovi messaggi per
Chaining external commands using pipes.
Inserendo la tua e-mail nella casella sotto, riceverai un avviso tramite posta elettronica ogni volta che il motore di ricerca troverà un nuovo messaggio per te
Il servizio è completamente GRATUITO!
x
Login to ForumsZone
Login with Google
Login with E-Mail & Password