Running command line commands within Ruby script

RubyCommand LineScriptingTerminalCommand Prompt

Ruby Problem Overview


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

Ruby Solutions


Solution 1 - Ruby

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.

Solution 2 - Ruby

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.

Solution 3 - Ruby

 folder = "/"
 list_all_files = "ls -al #{folder}"
 output = `#{list_all_files}`
 puts output

Solution 4 - Ruby

Yes this is certainly doable but the method of implementation differs dependant on whether the "command line" program in question operates in "Full screen" or command line mode. Programs written for the command line tend to read STDIN and write to STDOUT. These can be called directly within Ruby using the standard backticks methods and/or system/exec calls.

If the program operates in "Full Screen" mode like screen or vi then the approach has to be different. For programs like this you should look for a Ruby implementation of the "expect" library. This will allow you to script what you expect to see on screen and what to send when you see those particular strings appear on screen.

This is unlikely to be the best approach and you should probably look at what you are trying to achieve and find the relevant library/gem to do that rather than trying to automate an existing full screen application. As an example "Need assistance with serial port communications in Ruby" deals with Serial Port communications, a pre-cursor to dialing if that is what you want to achieve using the specific programs you mentioned.

Solution 5 - Ruby

The Most Used method is Using Open3 here is my code edited version of the above code with some corrections:

require 'open3'
puts"Enter the command for execution"
some_command=gets
stdout,stderr,status = Open3.capture3(some_command)
STDERR.puts stderr
if status.success?
  puts stdout
else
  STDERR.puts "ERRRR"
end

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiongeetfunView Question on Stackoverflow
Solution 1 - RubyAdrianView Answer on Stackoverflow
Solution 2 - RubyMark RushakoffView Answer on Stackoverflow
Solution 3 - RubyohhoView Answer on Stackoverflow
Solution 4 - RubySteve WeetView Answer on Stackoverflow
Solution 5 - RubyKeshav MaheshwariView Answer on Stackoverflow