问题
I'm trying to catch output of external program. Example:
#include <stdio.h>
#include <unistd.h>
#include <stddef.h>
int main() {
int i = 0;
while(i < 10) {
printf("i = %i\n", i++);
usleep(2000000);
}
return 0;
}
And here is my main.go:
package main
import (
"bufio"
"io"
"log"
"os/exec"
)
func reecho(closer io.ReadCloser) {
reader := bufio.NewReader(closer)
for {
s, e := reader.ReadString('\n')
if e != nil {
log.Println(e)
break
}
log.Println(s)
}
}
func main() {
cmd := exec.Command("./infcount")
log.Println("starting ", cmd)
stdout, err := cmd.StdoutPipe()
stderr, _ := cmd.StderrPipe()
if err != nil {
log.Fatal(err)
}
if err := cmd.Start(); err != nil {
log.Fatal(err)
}
go reecho(stdout)
go reecho(stderr)
if err := cmd.Wait(); err != nil {
log.Fatal(err)
}
}
The problem is buffering of stdout. "reecho" get data only when 4096 bytes in stdout buffer or program is exiting(for my short example). Is there way to decrease size of buffer to catch every line of output?
Update: Same binary 'infcount' works fine when ran from shell. It writes every 'i' to the screen.
回答1:
version of your C program that will track the output as it happens
#include <stdio.h>
#include <unistd.h>
#include <stddef.h>
int main() {
int i = 0;
while(i < 10) {
printf("i = %i\n", i++);
usleep(2000000);
fflush(stdout);
}
return 0;
}
If it is an existing precompiled program then stdbuf
may be able to fix it, see https://www.perkin.org.uk/posts/how-to-fix-stdio-buffering.html
来源:https://stackoverflow.com/questions/53831769/catch-buffered-stdout-output-of-exec-command