From: Robert Klemme Date: 2009-11-11T23:40:40+09:00 Subject: Re: Calling a subprocess with specific arguments and capturing its output? 2009/11/11 Dan Q : > On Tue, Nov 10, 2009 at 9:48 PM, Tony Arcieri wrote: >> On Tue, Nov 10, 2009 at 4:00 PM, Dan Q wrote: >> >>> I was looking for a function with a syntax that allows >>> separate arguments, like system("du", "-sh", filename) >>> >> >> Why is this any harder than? >> >> `#{cmd} #{args.map { |arg| arg.to_s.inspect }.join(' ')}` > > That comes a lot closer to working than I had expected ;) > I'd rather not deal with escaping, at all. Won't shell commands in > backticks be run differently, depending on what the system shell is? > I'm not sure whether all unix shells have similar escaping syntax. > > The escaping done by inspect() seems to fail when the filename begins > with whitespace or contains a newline. If you are on 1.9, escaping is superfluous: you can pass an Array of arguments directly: irb(main):001:0> IO.popen(%w{echo *}, "r") {|io| puts io.read} * => nil irb(main):002:0> IO.popen(["ls", "-a", "-F"], "r") {|io| puts io.read} ./ ../ => nil This is a lot safer, significantly less error prone and is probably more efficient as well (because there is no shell needed for parsing the command line). As far as I can see this does not work in 1.8.7. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/