Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.ruby > #7338 > unrolled thread
| Started by | Petter Gustad <newsmailcomp6@gustad.com> |
|---|---|
| First post | 2017-02-26 17:36 +0100 |
| Last post | 2017-02-26 22:53 +0100 |
| Articles | 4 — 2 participants |
Back to article view | Back to comp.lang.ruby
How to flush stdin to popen3 without closing it? Petter Gustad <newsmailcomp6@gustad.com> - 2017-02-26 17:36 +0100
Re: How to flush stdin to popen3 without closing it? Robert Klemme <shortcutter@googlemail.com> - 2017-02-26 18:42 +0100
Re: How to flush stdin to popen3 without closing it? Petter Gustad <newsmailcomp6@gustad.com> - 2017-02-26 22:46 +0100
Re: How to flush stdin to popen3 without closing it? Robert Klemme <shortcutter@googlemail.com> - 2017-02-26 22:53 +0100
| From | Petter Gustad <newsmailcomp6@gustad.com> |
|---|---|
| Date | 2017-02-26 17:36 +0100 |
| Subject | How to flush stdin to popen3 without closing it? |
| Message-ID | <8760jwkiyv.fsf@filestore.home.gustad.com> |
It seems like stdin must be closed for popen3 to send stdin to the
sub-process. How can I do something like this:
require 'open3'
stdin, stdout, stderr, wait_thr = Open3.popen3("dc")
stdin.puts "1 2 + p"
stdin.flush # does not not help
stdin.close # without this it will just hang on the read
res = stdout.read
puts "1+2 is #{res}"
#stdin.reopen # is it possible to re-open the stdin somehow?
stdin.puts "#{res} 2 * p"
stdin.close
res = stdout.read
puts "(1+2)*2 is #{res}"
...
Is there a way to flush or re-open stdin? Is there some other variation
of popen3 which can be used?
Thanks!
//Petter
--
.sig removed by request.
[toc] | [next] | [standalone]
| From | Robert Klemme <shortcutter@googlemail.com> |
|---|---|
| Date | 2017-02-26 18:42 +0100 |
| Message-ID | <ehgid3F3dm4U1@mid.individual.net> |
| In reply to | #7338 |
On 26.02.2017 17:36, Petter Gustad wrote:
>
> It seems like stdin must be closed for popen3 to send stdin to the
> sub-process. How can I do something like this:
>
> require 'open3'
>
> stdin, stdout, stderr, wait_thr = Open3.popen3("dc")
> stdin.puts "1 2 + p"
> stdin.flush # does not not help
> stdin.close # without this it will just hang on the read
> res = stdout.read
> puts "1+2 is #{res}"
> #stdin.reopen # is it possible to re-open the stdin somehow?
> stdin.puts "#{res} 2 * p"
> stdin.close
> res = stdout.read
> puts "(1+2)*2 is #{res}"
> ...
>
> Is there a way to flush or re-open stdin? Is there some other variation
> of popen3 which can be used?
You are missing one important point: stdout.read must block until dc
closes its output because there is no limit set on the read amount. And
that will only happen if dc's input has been closed because, obviously,
dc needs to be able to write results as long as input is coming. If you
replace that line with
res = stdout.gets
it will work the way you expect. You could also use stdout.sync=true to
avoid to have to use #flush all the time.
http://ruby-doc.org/core-2.4.0/IO.html#method-i-sync-3D
Kind regards
robert
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
[toc] | [prev] | [next] | [standalone]
| From | Petter Gustad <newsmailcomp6@gustad.com> |
|---|---|
| Date | 2017-02-26 22:46 +0100 |
| Message-ID | <87h93gd3s7.fsf@filestore.home.gustad.com> |
| In reply to | #7339 |
Robert Klemme <shortcutter@googlemail.com> writes:
> On 26.02.2017 17:36, Petter Gustad wrote:
>>
>> It seems like stdin must be closed for popen3 to send stdin to the
>> sub-process. How can I do something like this:
>>
>> require 'open3'
>>
>> stdin, stdout, stderr, wait_thr = Open3.popen3("dc")
>> stdin.puts "1 2 + p"
>> stdin.flush # does not not help
>> stdin.close # without this it will just hang on the read
>> res = stdout.read
>> puts "1+2 is #{res}"
>> #stdin.reopen # is it possible to re-open the stdin somehow?
>> stdin.puts "#{res} 2 * p"
>> stdin.close
>> res = stdout.read
>> puts "(1+2)*2 is #{res}"
>> ...
>>
>> Is there a way to flush or re-open stdin? Is there some other variation
>> of popen3 which can be used?
>
> You are missing one important point: stdout.read must block until dc
> closes its output because there is no limit set on the read amount.
> And that will only happen if dc's input has been closed because,
> obviously, dc needs to be able to write results as long as input is
> coming. If you replace that line with
>
> res = stdout.gets
>
> it will work the way you expect. You could also use stdout.sync=true
> to avoid to have to use #flush all the time.
>
> http://ruby-doc.org/core-2.4.0/IO.html#method-i-sync-3D
Thanks! Actually I was thinking readline, where I was writing read, and
of course the correct ruby method is gets...
require 'open3'
stdin, stdout, stderr, wait_thr = Open3.popen3("dc")
stdin.puts "1 2 + p"
res = stdout.gets
puts "1+2 is #{res}"
stdin.puts "#{res} 2 * p"
res = stdout.gets
puts "(1+2)*2 is #{res}"
The above results in:
1+2 is 3
(1+2)*2 is 6
Again, thanks!
Best regards
//Petter
--
.sig removed by request.
[toc] | [prev] | [next] | [standalone]
| From | Robert Klemme <shortcutter@googlemail.com> |
|---|---|
| Date | 2017-02-26 22:53 +0100 |
| Message-ID | <ehh12jF6dltU1@mid.individual.net> |
| In reply to | #7340 |
On 26.02.2017 22:46, Petter Gustad wrote: > Again, thanks! You're welcome! Just one more caveat, which might not apply in this case but a general advice for #popen and the likes: buffers between processes are limited. If you handle everything single threaded there is potential for deadlock. This will always happen if you send more data longer than the buffer size to the pipe and the other process will also send more than buffer size data. Then both are blocked on IO. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.ruby
csiph-web