Writing A Ruby Shell

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.

On 5/12/07, Philip W. [email protected] 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.

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/

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.

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.

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

On 5/12/07, Philip W. [email protected] 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:

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

Cheers,
Peter C.

On 5/12/07, Philip W. [email protected] 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/

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.