4

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.

3
  • ruby a.rb works perfectly fine Commented Jun 8, 2013 at 14:25
  • 1
    @temuri, have you played with any ideas at all as a start? For example a basic loop with print "$ " (not puts since it adds a cr/lf implicitly) for prompt, and gets to read input? Then, again at a basic level, do a system call on the string you grab from the user. Add more interesting behavior on top of that... Commented Jun 8, 2013 at 14:29
  • 5
    This is a huge topic, I can recommend this book: Build Awesome Command-Line Applications in Ruby: Control Your Computer, Simplify Your Life Commented Jun 8, 2013 at 14:30

5 Answers 5

7

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"

Sign up to request clarification or add additional context in comments.

3 Comments

Would 'strip' be better? To get rid of white space on front as well?
Use chomp instead of chop. The first is a surgical removal of trailing line-ending. The second is a indiscriminate removal of the last character in the string if a line end isn't found. Also chop doesn't remove "white space", it removes "\r\n". White space contains line ends, tabs, spaces, and line feeds/vertical tabs.
strip might be. Leading and trailing white space is usually not wanted when parsing commands. Also look at squeeze(' ').
1

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.

2 Comments

Remember to chomp the input received from gets. Failing to do that is the source of great pain when coding these sort of tools.
Good catch Tin Man. I updated and used 'strip' to get rid of white space on front and back.
1

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

1 Comment

I don't think Thor or Rake are going to be suitable as starting points. They're oriented toward command-line apps and performing system configuration and maintenance, which is contrary to the OP's statement: I do not need a CLI script that takes arguments. I need something that creates a shell interface. If you can show a simple example how they'd be used and be more effective I think you should add one.
1

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.

Comments

-1

Take a look at cliqr which comes with inbuilt support for build a custom shell https://github.com/anshulverma/cliqr/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.