[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Capturing error msgs from output = `cmd`

Victor Reyes

12/27/2007 2:53:00 AM

[Note: parts of this message were removed to make it a legal post.]

Hello Team,

I wrote the simple piece of code below which under "normal" circumstances it
works fine.
If, however, the command executed generates an error msg, the error is
displayed on the screen.
This is a behaviour which I don't want.
I would like to capture ALL output generated by the command and return it to
the caller.
I tried different tricks but nothing worked. The question is:

How can I capture ALL output from line: *userCMD_output = `#{input}`*
including stderr???

require 'socket'
port = 19557
server = TCPServer.new("", port)

while (session = server.accept)
input = session.gets
userCMD_output = `#{input}`
session.write("#{userCMD_output}")
session.close
end

while you are at it, is there any way to obtain the caller's hostname or IP
address?

Thank you

Victor

7 Answers

Tim Hunter

12/27/2007 3:04:00 AM

0

Victor Reyes wrote:
> Hello Team,
>
> I wrote the simple piece of code below which under "normal" circumstances it
> works fine.
> If, however, the command executed generates an error msg, the error is
> displayed on the screen.
> This is a behaviour which I don't want.
> I would like to capture ALL output generated by the command and return it to
> the caller.
> I tried different tricks but nothing worked. The question is:
>
> How can I capture ALL output from line: *userCMD_output = `#{input}`*
> including stderr???
>

When you use backticks to capture the output from a command, what you
get is whatever the command writes to stdout. If the command writes an
error message to stderr you can't capture it.

Check out the open3 library and the popen3 method instead.

$ ri Open3#popen3
----------------------------------------------------------- Open3#popen3
popen3(*cmd) {|| ...}
------------------------------------------------------------------------
Open stdin, stdout, and stderr streams and start external
executable. Non-block form:

require 'open3'

[stdin, stdout, stderr] = Open3.popen3(cmd)

Block form:

require 'open3'

Open3.popen3(cmd) { |stdin, stdout, stderr| ... }

The parameter cmd is passed directly to Kernel#exec.


--
RMagick: http://rmagick.ruby...

James Gray

12/27/2007 4:30:00 AM

0

On Dec 26, 2007, at 9:03 PM, Tim Hunter wrote:

> Victor Reyes wrote:
>> Hello Team,
>> I wrote the simple piece of code below which under "normal"
>> circumstances it
>> works fine.
>> If, however, the command executed generates an error msg, the error
>> is
>> displayed on the screen.
>> This is a behaviour which I don't want.
>> I would like to capture ALL output generated by the command and
>> return it to
>> the caller.
>> I tried different tricks but nothing worked. The question is:
>> How can I capture ALL output from line: *userCMD_output = `#{input}`*
>> including stderr???
>>
>
> When you use backticks to capture the output from a command, what
> you get is whatever the command writes to stdout. If the command
> writes an error message to stderr you can't capture it.

Well, you could fold STDERR into STDOUT. In my Unix shell that's done
with:

`#{cmd} 2>&1`

Hope that helps.

James Edward Gray II

Tom

12/27/2007 5:05:00 AM

0


On Dec 26, 2007, at 9:30 PM, James Gray wrote:

> On Dec 26, 2007, at 9:03 PM, Tim Hunter wrote:
>
>> Victor Reyes wrote:
>>> Hello Team,
>>> I wrote the simple piece of code below which under "normal"
>>> circumstances it
>>> works fine.
>>> If, however, the command executed generates an error msg, the
>>> error is
>>> displayed on the screen.
>>> This is a behaviour which I don't want.
>>> I would like to capture ALL output generated by the command and
>>> return it to
>>> the caller.
>>> I tried different tricks but nothing worked. The question is:
>>> How can I capture ALL output from line: *userCMD_output =
>>> `#{input}`*
>>> including stderr???
>>>
>>
>> When you use backticks to capture the output from a command, what
>> you get is whatever the command writes to stdout. If the command
>> writes an error message to stderr you can't capture it.
>
> Well, you could fold STDERR into STDOUT. In my Unix shell that's
> done with:
>
> `#{cmd} 2>&1`
>
> Hope that helps.
>
> James Edward Gray II
>

that's a great idea. alternately, you could use open3:

http://ruby-doc.org/stdlib/libdoc/open3/rdoc/...

it does make it a bit easier to do error checking/handling (by
differentiating stderr from stdout). you can use nil for the values
you don't want...

nil, stdout, stderr = popen3("cmd")

tom

Tom

12/27/2007 5:05:00 AM

0

just saw that i duplicated a response. sorry.

On Dec 26, 2007, at 9:30 PM, James Gray wrote:

> On Dec 26, 2007, at 9:03 PM, Tim Hunter wrote:
>
>> Victor Reyes wrote:
>>> Hello Team,
>>> I wrote the simple piece of code below which under "normal"
>>> circumstances it
>>> works fine.
>>> If, however, the command executed generates an error msg, the
>>> error is
>>> displayed on the screen.
>>> This is a behaviour which I don't want.
>>> I would like to capture ALL output generated by the command and
>>> return it to
>>> the caller.
>>> I tried different tricks but nothing worked. The question is:
>>> How can I capture ALL output from line: *userCMD_output =
>>> `#{input}`*
>>> including stderr???
>>>
>>
>> When you use backticks to capture the output from a command, what
>> you get is whatever the command writes to stdout. If the command
>> writes an error message to stderr you can't capture it.
>
> Well, you could fold STDERR into STDOUT. In my Unix shell that's
> done with:
>
> `#{cmd} 2>&1`
>
> Hope that helps.
>
> James Edward Gray II
>


Victor Reyes

12/27/2007 2:45:00 PM

0

[Note: parts of this message were removed to make it a legal post.]

Team,

First, thank you for all your suggestions. They are greatly appreciated.

I tried the:
*userCMD_output* *= `#{input} 2>&1`*
But could not capture the error. Matter of facts the error to the *ls *command
was displayed on the screen as:
*ls: 0653-341 The file totot does not exist. *

Second, I tried using the *Open3* method and when I tried to display the
content of stdin, stdout and stderr just to inspect their contents, this is
what's there:

*stdin, stdout, stderr = Open3.popen3(input)*

puts stdin
puts stdout
puts stderr

*#<IO:0x20060638>
#<IO:0x200605fc>
#<IO:0x20060598> *

It looks like I can't get this thing to work.

Thanks a bunch for all the help from everyone.

Victor

On Dec 27, 2007 12:05 AM, Tom Metge <tom@accident-prone.com> wrote:

> just saw that i duplicated a response. sorry.
>
> On Dec 26, 2007, at 9:30 PM, James Gray wrote:
>
> > On Dec 26, 2007, at 9:03 PM, Tim Hunter wrote:
> >
> >> Victor Reyes wrote:
> >>> Hello Team,
> >>> I wrote the simple piece of code below which under "normal"
> >>> circumstances it
> >>> works fine.
> >>> If, however, the command executed generates an error msg, the
> >>> error is
> >>> displayed on the screen.
> >>> This is a behaviour which I don't want.
> >>> I would like to capture ALL output generated by the command and
> >>> return it to
> >>> the caller.
> >>> I tried different tricks but nothing worked. The question is:
> >>> How can I capture ALL output from line: *userCMD_output =
> >>> `#{input}`*
> >>> including stderr???
> >>>
> >>
> >> When you use backticks to capture the output from a command, what
> >> you get is whatever the command writes to stdout. If the command
> >> writes an error message to stderr you can't capture it.
> >
> > Well, you could fold STDERR into STDOUT. In my Unix shell that's
> > done with:
> >
> > `#{cmd} 2>&1`
> >
> > Hope that helps.
> >
> > James Edward Gray II
> >
>
>
>

Stefano Crocco

12/27/2007 2:54:00 PM

0

Alle gioved=EC 27 dicembre 2007, Victor Reyes ha scritto:
> Team,
>
> First, thank you for all your suggestions. They are greatly appreciated.
>
> I tried the:
> *userCMD_output* *=3D `#{input} 2>&1`*
> But could not capture the error. Matter of facts the error to the *ls
> *command was displayed on the screen as:
> *ls: 0653-341 The file totot does not exist. *

Are you trying it in IRB? in this case, maybe what you see is the return=20
value. Try puts userCMD_output and see whether it contains the error messag=
e=20
or not. I tried this and it works:

irb(main):001:0> res =3D `ls abc 2>&1`
=3D> "ls: impossibile accedere a abc: No such file or directory\n"
irb(main):002:0> res
=3D> "ls: impossibile accedere a abc: No such file or directory\n"

> Second, I tried using the *Open3* method and when I tried to display the
> content of stdin, stdout and stderr just to inspect their contents, this =
is
> what's there:
>
> *stdin, stdout, stderr =3D Open3.popen3(input)*
>
> puts stdin
> puts stdout
> puts stderr
>
> *#<IO:0x20060638>
> #<IO:0x200605fc>
> #<IO:0x20060598> *

I don't understand how this works very well (I just started experimenting w=
ith=20
Open3 yesterday), but I think you need to call their read methods, just as=
=20
you'd do with a file:

puts stdout.read
=3D> ...

This won't work with stdin (if I remember correctly) because it's not open =
for=20
writing.

I hope this helps

Stefano

Victor Reyes

12/27/2007 3:57:00 PM

0

Hi, Stefano,

Well I have partial success at last!

The expression *res =3D `ls abc 2>&1`* works fine on the irb. But not outsi=
de
of it.

For the *Open3* method I tried your suggestion using the *stderr.read* and
it works fine.
I just needed a way to return the outcome of the request to the client
caller.
Since *Open3* works I will stay with it.

Thanks to you, Tim Hunter, James Edward Gray II and Tom Metge for all your
help. It is really appreciated.
One day, when I become good at using Ruby, I might be able to help others.

Victor


On Dec 27, 2007 9:53 AM, Stefano Crocco <stefano.crocco@alice.it> wrote:

> Alle gioved=EC 27 dicembre 2007, Victor Reyes ha scritto:
> > Team,
> >
> > First, thank you for all your suggestions. They are greatly appreciated=