Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running command line commands within Ruby script

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.)

like image 687
geetfun Avatar asked Jul 01 '10 16:07

geetfun


People also ask

How do you pass command-line arguments in Ruby?

How to Use Command-Line Arguments. In your Ruby programs, you can access any command-line arguments passed by the shell with the ARGV special variable. ARGV is an Array variable which holds, as strings, each argument passed by the shell.


2 Answers

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.

like image 57
Adrian Avatar answered Sep 30 '22 07:09

Adrian


There's a few ways to run system commands in Ruby.

irb(main):003:0> `date /t` # surround with backticks => "Thu 07/01/2010 \n" irb(main):004:0> system("date /t") # system command (returns true/false) Thu 07/01/2010 => true irb(main):005:0> %x{date /t} # %x{} wrapper => "Thu 07/01/2010 \n" 

But if you need to actually perform input and output with the command's stdin/stdout, you'll probably want to look at the IO::popen method, which specifically offers that facility.

like image 42
Mark Rushakoff Avatar answered Sep 30 '22 05:09

Mark Rushakoff