Golang subcommand pipe output in real time

I'm trying to pipe the output of a command, but no data is read from the pipe until the end of the write is closed. Ultimately I want this connection to a Web site that communicates the status of a command while it is running. The problem is that while this code prints messages one by one, it doesn't print anything until the program finishes executing.

cmd := exec.Command(MY_SCRIPT_LOCATION, args)

// create a pipe for the output of the script
// TODO pipe stderr too
cmdReader, err := cmd.StdoutPipe()
if err != nil {
    fmt.Fprintln(os.Stderr, "Error creating StdoutPipe for Cmd", err)
    return
}

scanner := bufio.NewScanner(cmdReader)
go func() {
    for scanner.Scan() {
        fmt.Printf("\t > %s\n", scanner.Text())
    }
}()

err = cmd.Start()
if err != nil {
    fmt.Fprintln(os.Stderr, "Error starting Cmd", err)
    return
}

err = cmd.Wait()
if err != nil {
    fmt.Fprintln(os.Stderr, "Error waiting for Cmd", err)
    return
}

      

Is there a way to do something like this, and the scanner is actually read in turn as it is written to the pipe and not after everything has been written? The program takes about 20 seconds to run and there is a constant stream of updates, so it's annoying to have them all go through at once.

+3


source to share


1 answer


It turns out that the problem is not in the code I wrote above. This works as expected. The problem was that the C program that was running was not properly cleaned up stdout

. When run interactively, it worked as expected, but when it stdout

was piped, it wouldn't actually be recorded until I called flush

. After you manually added some flash statements to c program, the go code worked as expected.



+4


source







All Articles