Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to capture loop code output

Tags:

c

linux

ruby

here is my loop code

#exe2.rb
loop do
  print "#{::Time.now}\r"
  sleep 1
end

and I use following c to capture its out:

fp = popen("ruby /home/roroco/Dropbox/rbs/ro_cmds/exe2.rb", "r");
while (fgets(var, sizeof(var), fp) != NULL) {
    printf("%s", var);
}

but it stuck in fgets, how to make it work?

like image 749
iufachajov Avatar asked Jun 27 '26 05:06

iufachajov


1 Answers

This is an effect of buffering. In UNIX stdout is line-buffered by default, which means that the stdio facility accumulates bytes till some buffer fills or it encounters a '\n'. This is beneficial to limit I/O thus improving performance (I/O is slow).

For this reason, change your ruby code to print a new line '\n' at the end instead of a carriage return '\r' (because fgets(3) is for lines). You don't need to change the C code as fgets(3) doesn't chomp the newline.

The Ruby interpreter treats stdout the same, unless it's a pipe. If that's the case it's fully buffered. The easiest way to get around that is doing a STDOUT.flush after every write in the ruby script.

like image 149
a3f Avatar answered Jun 28 '26 19:06

a3f