Is there a way to run command line commands through Ruby? I'm trying to create a small little Ruby program that would dial out and receive/send through command line programs like 'screen', 'rcsz', etc.
It would be great if I could tie all this in with Ruby (MySQL backend, etc.)
Yes. There are several ways:
a. Use %x
or '`':
%x(echo hi) #=> "hi\n"
%x(echo hi >&2) #=> "" (prints 'hi' to stderr)
`echo hi` #=> "hi\n"
`echo hi >&2` #=> "" (prints 'hi' to stderr)
These methods will return the stdout, and redirect stderr to the program's.
b. Use system
:
system 'echo hi' #=> true (prints 'hi')
system 'echo hi >&2' #=> true (prints 'hi' to stderr)
system 'exit 1' #=> nil
This method returns true
if the command was successful. It redirects all output to the program's.
c. Use exec
:
fork { exec 'sleep 60' } # you see a new process in top, "sleep", but no extra ruby process.
exec 'echo hi' # prints 'hi'
# the code will never get here.
That replaces the current process with the one created by the command.
d. (ruby 1.9) use spawn
:
spawn 'sleep 1; echo one' #=> 430
spawn 'echo two' #=> 431
sleep 2
# This program will print "two\none".
This method does not wait for the process to exit and returns the PID.
e. Use IO.popen
:
io = IO.popen 'cat', 'r+'
$stdout = io
puts 'hi'
$stdout = IO.new 0
p io.read(1)
io.close
# prints '"h"'.
This method will return an IO
object that reperesents the new processes' input/output. It is also currently the only way I know of to give the program input.
f. Use Open3
(on 1.9.2 and later)
require 'open3'
stdout,stderr,status = Open3.capture3(some_command)
STDERR.puts stderr
if status.successful?
puts stdout
else
STDERR.puts "OH NO!"
end
Open3
has several other functions for getting explicit access to the two output streams. It's similar to popen, but gives you access to stderr.