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
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.rubyforge.org/
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
···
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.
that's a great idea. alternately, you could use open3:
http://ruby-doc.org/stdlib/libdoc/open3/rdoc/index.html
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
···
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
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
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
>
Alle giovedì 27 dicembre 2007, Victor Reyes ha scritto:
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. *
Are you trying it in IRB? in this case, maybe what you see is the return
value. Try puts userCMD_output and see whether it contains the error message
or not. I tried this and it works:
irb(main):001:0> res = `ls abc 2>&1`
=> "ls: impossibile accedere a abc: No such file or directory\n"
irb(main):002:0> res
=> "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 = 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 with
Open3 yesterday), but I think you need to call their read methods, just as
you'd do with a file:
puts stdout.read
=> ...
This won't work with stdin (if I remember correctly) because it's not open for
writing.
I hope this helps
Stefano
Hi, Stefano,
Well I have partial success at last!
The expression *res = `ls abc 2>&1`* works fine on the irb. But not outside
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ì 27 dicembre 2007, Victor Reyes ha scritto:
> 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. *
Are you trying it in IRB? in this case, maybe what you see is the return
value. Try puts userCMD_output and see whether it contains the error
message
or not. I tried this and it works:
irb(main):001:0> res = `ls abc 2>&1`
=> "ls: impossibile accedere a abc: No such file or directory\n"
irb(main):002:0> res
=> "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 = 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
with
Open3 yesterday), but I think you need to call their read methods, just as
you'd do with a file:
puts stdout.read
=> ...
This won't work with stdin (if I remember correctly) because it's not open
for
writing.
I hope this helps
Stefano