How do I write shell-like scripts using Ruby?

11,381

Solution 1

The type of program you require can easily be made with just a few simple constructs. I know you're not asking for a solution, but I'll just give you a skeleton to start off and play around with:

#!/usr/bin/env ruby
def prnthelp
  puts "Hello sir, what would you like to do?"
  puts "1: dir"
  puts "2: exit"
end

def loop
  prnthelp
  case gets.chomp.to_i
    when 1 then puts "you chose dir!"
    when 2 then puts "you chose exit!"
      exit
  end
  loop
end

loop

Anyways, this is a simplistic example on how you could do it, but probably the book recommended in the comments is better. But this is just to get you off.

Some commands to get you started are:

somevar = gets

This gets user input. Maybe learn about some string methods to manipulate this input can do you some good. http://ruby-doc.org/core-2.0/String.html chomp will chop off any whitespace, and to_i converts it to an integer.

Some commands to do Unix stuff:

system('ls -la') #=> outputs the output of that command
exit #=> exits the program

Anyways, if you want this kind of stuff, I think it's not a bad idea to look into http://www.codecademy.com/ basically they teach you Ruby by writing small scripts such as these. However, they maybe not be completely adapted to Unix commands, but user input and the likes are certainly handled.


Edit:

As pointed out do use this at the top of your script:

#!/usr/bin/env ruby

Edit:

Example of chomp vs. chop:

full_name = "My Name is Ravikanth\r\n" 
full_name.chop! # => "My Name is Ravikanth"

Now if you run chop and there are no newline characters:

puts full_name    #=> "My Name is Ravikanth"
full_name.chop!  #=> "My Name is Ravikant"

versus:

puts full_name       #=> "My Name is Ravikanth\r\n"

full_name.chomp!  #=> "My Name is Ravikanth"
full_name.chomp!  #=> "My Name is Ravikanth"

See: "Ruby Chop vs Chomp"

Solution 2

Here's a really basic loop:

#!/user/bin/ruby
#
while true do
  print "$ "
  $stdout.flush
  inputs = gets.strip
  puts "got your input: #{inputs}"
  # Check for termination, like if they type in 'exit' or whatever...
  # Run "system" on inputs like 'dir' or whatever...
end

As Stefan mentioned in a comment, this is a huge topic and there are scenarios that will make this complicated. This is, as I say, a very basic example.

Solution 3

Use irb. I was looking into an alternative to bash and was thinking along the same lines... but ended up choosing fish: http://fishshell.com/

Nonetheless, I was thinking of using irb and going along the lines of irbtools: https://github.com/janlelis/irbtools

Example:

> irb
Welcome to IRB. You are using ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-linux]. Have fun ;)
>> ls #=> ["bin", "share", "opt", "lib", "var", "etc", "src"]
>>

In any case, irb is the ruby shell.

Solution 4

Adding to the two other (valid) answers posted so far be wary of using #!/usr/bin/ruby, because ruby isn't always installed there. You can use this instead:

#!/usr/bin/env ruby

Or if you want warnings:

#!/usr/bin/env ruby -w

That way, your script will work irrespective of differences where ruby might be installed on your server and your laptop.

Edit: also, be sure to look into Thor and Rake.

http://whatisthor.com

http://rake.rubyforge.org

Share:
11,381
temuri
Author by

temuri

Updated on June 18, 2022

Comments

  • temuri
    temuri almost 2 years

    I have a task of writing a simple Ruby script which would do the following.

    Upon execution from the UNIX command line, it would present the user with a prompt at which he should be able to run certain commands, like "dir", "help" or "exit". Upon "exit" the user should return to the Unix shell.

    I'm not asking for the solution; I would just like to know how this "shell" functionality can be implemented in Ruby. How do you present the user with a prompt and interpret commands.

    I do not need a CLI script that takes arguments. I need something that creates a shell interface.