# Writing A Ruby Shell

**URL:** <https://www.ruby-forum.com/t/writing-a-ruby-shell/103997>\
**Category:** Ruby\
**Created:** [May 12, 2007, 4:23pm UTC](https://www.ruby-forum.com/t/writing-a-ruby-shell/103997 "2007-05-12T16:23:41Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![pdubb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/e0b2c6/32.png) [@pdubb](https://www.ruby-forum.com/u/pdubb)\
**Post date:** [May 12, 2007, 4:23pm UTC](https://www.ruby-forum.com/t/writing-a-ruby-shell/103997/1 "2007-05-12T16:23:41Z")

</div>

Hello all,

```
I'm writing a Ruby shell for Ubuntu Linux 7.04. I would like my

```

shell to take commands from the user, run the command, output the result  
to the command line, and log the result in a file. But I am having  
trouble getting the Ruby shell to output the result to the command line,  
and log the command. I’ve tried everything I can think of - using the  
backticks method (``), exec(), system(), and IO.popen, strange  
combinations of the mentioned and eval(), but nothing satisfies both of  
my requirements. Sometimes the shell will output the command result to  
the shell, but it won’t log it. Sometimes it will log the command  
result, but it won’t output it to the shell. Sometimes it does one or  
both things, but it only outputs or logs some of the command result. I  
would appreciate any help that I could get on ways to make this work.

Thanks,  
Philip W.

---

<div class="post-metadata">

**Author:** ![pdubb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/e0b2c6/32.png) [@pdubb](https://www.ruby-forum.com/u/pdubb)\
**Post date:** [May 12, 2007, 4:55pm UTC](https://www.ruby-forum.com/t/writing-a-ruby-shell/103997/2 "2007-05-12T16:55:44Z")

</div>

On 5/12/07, Philip W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> my requirements. Sometimes the shell will output the command result to  
> the shell, but it won’t log it. Sometimes it will log the command  
> result, but it won’t output it to the shell. Sometimes it does one or  
> both things, but it only outputs or logs some of the command result. I  
> would appreciate any help that I could get on ways to make this work.

Perhaps I’m missing your ultimate point here, but one major problem I  
see is  
that you can’t really just slurp out the “results” for, say, a text  
editor  
(such as vi or pico) or any sort of interactive script. If your shell  
doesn’t allow access to those sort of programs, it wouldn’t be  
particularly  
useful (unless you envision a use for a shell that only allows you to  
perform the most basic of commands).

Is it necessary to log all output? Generally “system” will give you the  
closest (but not exact) match to what happens when you normally run a  
program under a shell, but of course that doesn’t return the output of  
the  
command you run… although it does let you get into interactive apps,  
etc.

From what I can tell, the main problem you appear to be running into is  
that  
some programs are not just sending output to stdout, or are redefining  
what  
stdout is. This is why shells often do lots of freaky things to make  
sure  
output ends up where it should.

Cheers,  
Peter C.

> **[Ruby Inside: The Ruby Blog](http://www.rubyinside.com/)**
>
> The biggest Ruby and Rails blog since 2006 - tutorials, news, and lots more

---

<div class="post-metadata">

**Author:** ![pdubb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/e0b2c6/32.png) [@pdubb](https://www.ruby-forum.com/u/pdubb)\
**Post date:** [May 12, 2007, 5:09pm UTC](https://www.ruby-forum.com/t/writing-a-ruby-shell/103997/3 "2007-05-12T17:09:56Z")

</div>

Peter C. wrote:

> > combinations of the mentioned and eval(), but nothing satisfies both of  
> > editor  
> > command you run… although it does let you get into interactive apps,  
> > Peter C.  
> > [http://www.rubyinside.com/](http://www.rubyinside.com/)

I would like to log all output, but if it came down to it I could do  
without logging all output. What I’m shooting for with my shell in terms  
of interactiveness is the closest match to running a command under a  
regular shell.

---

<div class="post-metadata">

**Author:** ![pdubb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/e0b2c6/32.png) [@pdubb](https://www.ruby-forum.com/u/pdubb)\
**Post date:** [May 12, 2007, 8:31pm UTC](https://www.ruby-forum.com/t/writing-a-ruby-shell/103997/4 "2007-05-12T20:31:15Z")

</div>

On Sat, May 12, 2007 at 11:23:03PM +0900, Philip W. wrote:

> both things, but it only outputs or logs some of the command result. I  
> would appreciate any help that I could get on ways to make this work.

Depending on what you’re trying to do, the following might be useful:

$ script log.txt  
$ irb  
… do some stuff  
irb\> quit  
$ exit  
$ cat log.txt

If you want to take a single line of Ruby and execute it, then you can  
consider using eval(). Most Ruby code which writes to standard output  
actually uses the variable $stdout (similarly $stdin for input and  
$stderr  
for error messages), so you can reassign $stdout and $stderr to a  
different  
IO object (e.g. a StringIO) to catpure it.

However, if the Ruby code you’re running in turn runs some external  
system  
program, e.g. system(“ls”), then that won’t work. What you’d need to do  
then  
is to run the command in a completely separate process. Look at  
IO.popen("-"). Look at open3.rb in the standard library if you need to  
capture stderr as well.

Regards,

Brian.

---

<div class="post-metadata">

**Author:** ![pdubb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/e0b2c6/32.png) [@pdubb](https://www.ruby-forum.com/u/pdubb)\
**Post date:** [May 13, 2007, 8:56pm UTC](https://www.ruby-forum.com/t/writing-a-ruby-shell/103997/5 "2007-05-13T20:56:09Z")

</div>

On 12.05.2007 16:23, Philip W. wrote:

> only outputs or logs some of the command result. I would appreciate any  
> help that I could get on ways to make this work.

Philip, please show some code. Please also note that this topic has  
been discussed a number of times here already. Maybe you can use IRB’s  
code as a start - or even modify it to suit your needs.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![pdubb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/e0b2c6/32.png) [@pdubb](https://www.ruby-forum.com/u/pdubb)\
**Post date:** [May 12, 2007, 5:17pm UTC](https://www.ruby-forum.com/t/writing-a-ruby-shell/103997/6 "2007-05-12T17:17:56Z")

</div>

On 5/12/07, Philip W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I would like to log all output, but if it came down to it I could do  
> without logging all output. What I’m shooting for with my shell in terms  
> of interactiveness is the closest match to running a command under a  
> regular shell.

I just remembered a page you might find useful:

> **[Ruby Kernel system, exec and %x](http://blog.jayfields.com/2006/06/ruby-kernel-system-exec-and-x.html)**
>
> The Ruby Core Library documentation is very similar for Kernel.system , Kernel.exec and %x\[..\] . Recently I needed to kick off a system pr...

Best of luck, I’ve rather fancied having a Ruby-esque shell for a while  
now…

Cheers,  
Peter C.

> **[Ruby Inside: The Ruby Blog](http://www.rubyinside.com/)**
>
> The biggest Ruby and Rails blog since 2006 - tutorials, news, and lots more

---

<div class="post-metadata">

**Author:** ![pdubb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/e0b2c6/32.png) [@pdubb](https://www.ruby-forum.com/u/pdubb)\
**Post date:** [May 18, 2007, 8:06pm UTC](https://www.ruby-forum.com/t/writing-a-ruby-shell/103997/7 "2007-05-18T20:06:00Z")

</div>

On 5/12/07, Philip W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> the shell, but it won’t log it. Sometimes it will log the command  
> result, but it won’t output it to the shell. Sometimes it does one or  
> both things, but it only outputs or logs some of the command result. I  
> would appreciate any help that I could get on ways to make this work.

I have years wanting something like that.

Luckily now I have some code for Ruby that you might want to use:  
[http://snipplr.com/view/2669/sheller/](http://snipplr.com/view/2669/sheller/)

It allows you to do things like:

sh = Sheller.new  
sh.do(“cd /tmp”)  
r = sh.do(“ls”)  
p r.stdout

Of course, this is the base class, I have other that make use of it  
and allow things like output highlighting and XML scripts; not  
completely finished, but working.

IMHO this kinds of things have a lot of future, it’s just a matter of  
implementing all sorts of crazy ideas.
