How do I call shell commands from inside of a Ruby program? How do I then get output from these commands back into Ruby?
Some things to think about when choosing between these mechanisms are:
You may need anything from simple backticks (``), system()
, and IO.popen
to full-blown Kernel.fork
/Kernel.exec
with IO.pipe
and IO.select
.
You may also want to throw timeouts into the mix if a sub-process takes too long to execute.
Unfortunately, it very much depends.
The way I like to do this is using the %x
literal, which makes it easy (and readable!) to use quotes in a command, like so:
directorylist = %x[find . -name '*test.rb' | sort]
Which, in this case, will populate file list with all test files under the current directory, which you can process as expected:
directorylist.each do |filename|
filename.chomp!
# work with file
end
You can also use the backtick operators (`), similar to Perl:
directoryListing = `ls /`
puts directoryListing # prints the contents of the root directory
Handy if you need something simple.
Which method you want to use depends on exactly what you're trying to accomplish; check the docs for more details about the different methods.
We can achieve it in multiple ways.
Using Kernel#exec
, nothing after this command is executed:
exec('ls ~')
Using backticks or %x
`ls ~`
=> "Applications\nDesktop\nDocuments"
%x(ls ~)
=> "Applications\nDesktop\nDocuments"
Using Kernel#system
command, returns true
if successful, false
if unsuccessful and returns nil
if command execution fails:
system('ls ~')
=> true
My favourite is Open3
require "open3"
Open3.popen3('nroff -man') { |stdin, stdout, stderr| ... }
I'm definitely not a Ruby expert, but I'll give it a shot:
$ irb
system "echo Hi"
Hi
=> true
You should also be able to do things like:
cmd = 'ls'
system(cmd)