package main import ( "bufio" "context" "fmt" "io" "log" "os" "os/exec" "time" ) func main() { if err := run(); err != nil { log.Fatal(err) } } func run() error { ctx, cancel := context.WithCancel(context.Background()) defer cancel() cmd := exec.CommandContext(ctx, "go", "run", "child/main.go") stdout, err := cmd.StdoutPipe() if err != nil { return err } defer stdout.Close() cmd.Stderr = os.Stderr cmd.Env = os.Environ() if err := cmd.Start(); err != nil { return err } cr, err := getCancelableReader(stdout) if err != nil { return err } if err := scan(cr); err != nil { return err } return cmd.Wait() } type cancelableReader interface { io.Reader SetReadDeadline(time.Time) error } func getCancelableReader(r io.Reader) (cancelableReader, error) { if cr := r.(cancelableReader); cr != nil { return cr, nil } return nil, fmt.Errorf("not a cancelable reader") } func scan(cr cancelableReader) error { scanner := bufio.NewScanner(cr) for scanner.Scan() { if err := cr.SetReadDeadline(time.Now().Add(2 * time.Second)); err != nil { return err } fmt.Println("scanned", scanner.Text()) } return scanner.Err() }