Another approach I had tried was to use IO.select, as shown in http://whynotwiki.com/Ruby_/_Process_management ( attributed to Jamis
Buck). This too, produced the same delay in output, but is shown below:
Thank you for any help
def read_until(pipe, stop_at, verbose = true)
lines = []
line = “”
while result = IO.select([pipe]) #, nil, nil, 10)
next if result.empty?
c = pipe.read(1)
break if c.nil?
line << c
break if line =~ stop_at
# Start a new line?
if line[-1] == ?\n
puts line if verbose
lines << line
line = ""
end
end
lines
end
Paul Winward wrote:
Thanks for the suggestion but I’m still having the problem.
Paul
ara.t.howard wrote:
On May 9, 2008, at 6:08 PM, Paul Winward wrote:
Note, I’m avoiding STDOUT.flush in sleep.rb since I won’t be able to
change the actual scripts I’ll be passing to popen3.
popen3 is going to be using fork/exec under the hood and should
inherit the sync setting of STDOUT, so try setting
STDOUT.sync = true
before the popen and see if that helps - untested, but i’m running out
the door…
The perl solution is system dependent, but it worked for me on Linux
2.6.22. I did see a debian package libpty-ruby but I don’t see any
documentation and am not sure if this is still supported.
The notion of a pseudo tty is new to me and I’d appreciate any help. Is
there a ruby equivalent for the perl solution below?
Thanks
#!/usr/bin/perl -w
use strict;
use IO::Pty;
my $pty = new IO::Pty;
my $slave = $pty->slave();
my $pid = fork();
die “Couldn’t fork: $!” unless defined $pid;
if($pid){ # dup STDOUT to Pty and run external program:
$pty->close_slave();
open(STDOUT, “>&”,$pty)||die $!;
system “perl blackbox.pl”;
print “\cD”; # send ^d to end
} else { # this is your monitoring process
$pty->make_slave_controlling_terminal();
print “*$_” while <$slave>;
exit;
} END
Paul Winward wrote:
Another approach I had tried was to use IO.select, as shown in http://whynotwiki.com/Ruby_/_Process_management ( attributed to Jamis
Buck). This too, produced the same delay in output, but is shown below:
Thank you for any help
def read_until(pipe, stop_at, verbose = true)
lines = []
line = “”
while result = IO.select([pipe]) #, nil, nil, 10)
next if result.empty?
c = pipe.read(1)
break if c.nil?
line << c
break if line =~ stop_at
# Start a new line?
if line[-1] == ?\n
puts line if verbose
lines << line
line = ""
end
end
lines
end
Paul Winward wrote:
Thanks for the suggestion but I’m still having the problem.
Paul
ara.t.howard wrote:
On May 9, 2008, at 6:08 PM, Paul Winward wrote:
Note, I’m avoiding STDOUT.flush in sleep.rb since I won’t be able to
change the actual scripts I’ll be passing to popen3.
popen3 is going to be using fork/exec under the hood and should
inherit the sync setting of STDOUT, so try setting
STDOUT.sync = true
before the popen and see if that helps - untested, but i’m running out
the door…
Thanks for the suggestion but I’m still having the problem.
if the child program makes a call to setvbuf (as ruby does) there is
little you can do to alter this behaviour. otherwise the ‘normal’
approach will work:
Thanks for the pointers. I wasn’t aware of setvbuf. I’ll look more into
pty.
ara.t.howard wrote:
On May 10, 2008, at 12:08 AM, Paul Winward wrote:
Thanks for the suggestion but I’m still having the problem.
if the child program makes a call to setvbuf (as ruby does) there is
little you can do to alter this behaviour. otherwise the ‘normal’
approach will work:
The perl solution is system dependent, but it worked for me on Linux
2.6.22. I did see a debian package libpty-ruby but I don’t see any
documentation and am not sure if this is still supported.
The notion of a pseudo tty is new to me and I’d appreciate any
help. Is
there a ruby equivalent for the perl solution below?
pty is supported and the dist has a bunch of demo code in it (ext/pty/
*) but you cannot capture stderr akaikt.
before the popen and see if that helps - untested, but i’m running out the
door…
IMHO that can only work if you use fork with a block. Since Paul
wants to start a new process that cannot possibly inherit buffering
settings that way. Since Ruby decides buffering mode of stdout based
on the type (i.e. if it is a terminal then sync = true otherwise not)
and the child process cannot be influenced by Paul it follows that the
only feasible way to use would be to present a tty as stdout to the
child (via some form of pseudo tty mechanism). But that may have
adverse effects because some programs change their output based on the
type of stdout as well (just think about including colorization on
ttys and omitting it on pipes).
This is the place to ask: Paul, what do you need that behavior for?
Maybe there are other mechanism to use.
Kind regards
robert
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.