Search code examples
gononblocking

How to do non-blocking Read() for io.PipeRaeder in Golang


I have following code. The executable program will send some text to stdout after 5 seconds. So, in.ReadLine() will block until receive data. How can I set a timeout for ReadLine() or do it in a non-blocking way?

package main

import (
    "bufio"
    "fmt"
    "io"
    "os/exec"
)

func main() {
    cmd := exec.Command("/path/to/executable")

    stdoutReader, stdoutWriter := io.Pipe()

    cmd.Stdout = stdoutWriter

    cmd.Start()

    in := bufio.NewReader(stdoutReader)
    b, _, _ := in.ReadLine()

    fmt.Println(string(b))
}


Solution

  • Thanks for the comments. I figure it out.

    package main
    
    import (
        "bufio"
        "fmt"
        "io"
        "os/exec"
        "time"
    )
    
    func main() {
        ch := make(chan []byte)
        cmd := exec.Command("/path/to/executable")
        stdoutReader, stdoutWriter := io.Pipe()
    
        cmd.Stdout = stdoutWriter
    
        if err := cmd.Start(); err != nil {
            return
        }
    
        in := bufio.NewReader(stdoutReader)
    
        go func() {
            b, _, _ := in.ReadLine()
            ch <- b
        }()
    
        complete := false
        for !complete {
            select {
            case s := <-ch:
                fmt.Println(string(s))
                complete = true
            case <-time.After(time.Second * 5):
                fmt.Println("timeout")
                complete = true
            }
        }
    
    }