[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

System commands with streaming output

Alex Wayne

4/8/2008 7:09:00 PM

I have a long running system command that I want to print the output
from a ruby script. Basically, this system command runs like a daemon
and prints output. So it I just use:

`./mycommand foo`

The output is completely supressed, and my ruby script simply appears to
hang.

So how can I execute a system command and have the output streamed back
to the terminal before the command finishes?
--
Posted via http://www.ruby-....

8 Answers

Tim Hunter

4/8/2008 7:12:00 PM

0

Alex Wayne wrote:
> I have a long running system command that I want to print the output
> from a ruby script. Basically, this system command runs like a daemon
> and prints output. So it I just use:
>
> `./mycommand foo`
>
> The output is completely supressed, and my ruby script simply appears to
> hang.
>
> So how can I execute a system command and have the output streamed back
> to the terminal before the command finishes?

ri IO::popen
--
Posted via http://www.ruby-....

Alex Wayne

4/8/2008 7:37:00 PM

0

Tim Hunter wrote:
> Alex Wayne wrote:
>> I have a long running system command that I want to print the output
>> from a ruby script. Basically, this system command runs like a daemon
>> and prints output. So it I just use:
>>
>> `./mycommand foo`
>>
>> The output is completely supressed, and my ruby script simply appears to
>> hang.
>>
>> So how can I execute a system command and have the output streamed back
>> to the terminal before the command finishes?
>
> ri IO::popen

Hmm, I still can't seem to get this working. I got this:

IO.popen './mycommand foo' do |f|
puts f.gets
end

It's doing its job, but I still get no output on the terminal. And to
be clear, when this command is run on its own I definitely get output.
--
Posted via http://www.ruby-....

Tim Hunter

4/8/2008 7:54:00 PM

0

Alex Wayne wrote:
> Tim Hunter wrote:
>> Alex Wayne wrote:
>>> I have a long running system command that I want to print the output
>>> from a ruby script. Basically, this system command runs like a daemon
>>> and prints output. So it I just use:
>>>
>>> `./mycommand foo`
>>>
>>> The output is completely supressed, and my ruby script simply appears to
>>> hang.
>>>
>>> So how can I execute a system command and have the output streamed back
>>> to the terminal before the command finishes?
>>
>> ri IO::popen
>
> Hmm, I still can't seem to get this working. I got this:
>
> IO.popen './mycommand foo' do |f|
> puts f.gets
> end
>
> It's doing its job, but I still get no output on the terminal. And to
> be clear, when this command is run on its own I definitely get output.

Possibly the command is writing to stderr instead of stdout. What
happens when you do this?

/mycommand foo >mycommand.stdout 2>mycommand.stderr

Does mycommand.stdout have the output, or mycommand.stderr? If the
latter, then the command is writing to stderr, and you're going to have
to use popen3 instead of plain popen:
http://ruby-doc.org/stdlib/libdoc/open3/rdoc/..., or if you don't
need to distinguish between the two, you could simply re-direct stderr
to stdout. I'm doing this from memory but I believe this should work:

IO.popen './mycommand foo >2&1' do...
--
Posted via http://www.ruby-....

Alex Wayne

4/8/2008 8:29:00 PM

0

Tim Hunter wrote:
> Possibly the command is writing to stderr instead of stdout. What
> happens when you do this?
>
> ./mycommand foo >mycommand.stdout 2>mycommand.stderr

pretty sure thats not it. Running that gives me no output at all.

I tried a super simple scenario.

test.rb:
#!/usr/local/bin/ruby
IO.popen('./foo.rb') { |f| puts f.gets }

foo.rb:
#!/usr/local/bin/ruby
10.times do |i|
puts i
sleep 0.5
end

When I run "./foo.rb" I get a slow count to 10, as expected.

When I run "./test.rb" I get a 5 second pause followed by a "0", then it
exits.

So it looks the block passed to popen isnt even getting called until the
command that it invokes exits. Then the variable passed into the block
is the entire output of that command?
--
Posted via http://www.ruby-....

Tim Hunter

4/8/2008 8:52:00 PM

0

Alex Wayne wrote:
> So it looks the block passed to popen isnt even getting called until the
> command that it invokes exits. Then the variable passed into the block
> is the entire output of that command?

It seems possible that there is some buffering going on. Perhaps
somebody else will have a better idea.

--
RMagick: http://rmagick.ruby...
RMagick 2: http://rmagick.ruby...rmagick2.html

Jens Wille

4/8/2008 9:00:00 PM

0

hi alex!

i'm sorry, i didn't follow the whole thread, but you probably want
to modify your simple example like so:

---- [ foo.rb ] ----
# immediately flush all output to the underlying OS
STDOUT.sync = true

10.times do |i|
puts i
sleep 0.5
end
--------------------

---- [ test.rb ] ----
IO.popen('./foo.rb') { |f|
until f.eof?
puts f.gets
end
}
---------------------

Alex Wayne [2008-04-08 22:29]:
> So it looks the block passed to popen isnt even getting called
> until the command that it invokes exits.
well, output is buffered first. only when that buffer is filled,
your receiving end of the pipe will see it. which, in this case,
coincides with the program's exit. if you don't want buffering to
happen, you have to set the sync mode to true (see [1]).

> Then the variable passed into the block is the entire output of
> that command?
it just reads the first line from that output, that's what IO#gets
does (see [2]).

[1] <http://www.ruby-doc.org/core/classes/IO.html#M...
[2] <http://www.ruby-doc.org/core/classes/IO.html#M...

hth
jens

--
Jens Wille, Dipl.-Bibl. (FH)
prometheus - Das verteilte digitale Bildarchiv für Forschung & Lehre
Kunsthistorisches Institut der Universität zu Köln
Albertus-Magnus-Platz, D-50923 Köln
Tel.: +49 (0)221 470-6668, E-Mail: jens.wille@uni-koeln.de
http://www.prometheus-bild...

Ezra Zygmuntowicz

4/8/2008 9:04:00 PM

0


On Apr 8, 2008, at 1:52 PM, Tim Hunter wrote:
> Alex Wayne wrote:
>> So it looks the block passed to popen isnt even getting called
>> until the command that it invokes exits. Then the variable passed
>> into the block is the entire output of that command?
>
> It seems possible that there is some buffering going on. Perhaps
> somebody else will have a better idea.
>
> --
> RMagick: http://rmagick.ruby...
> RMagick 2: http://rmagick.ruby...rmagick2.html
>



add this to the top of your script:

$stdout.sync = true


That will stop it from buffering and will flush the output every time
you call puts

Cheers-

- Ezra Zygmuntowicz
-- Founder & Software Architect
-- ezra@engineyard.com
-- EngineYard.com


Alex Wayne

4/8/2008 11:47:00 PM

0

Thanks guys. You all rock.

--
Posted via http://www.ruby-....