I have a function named print()
that print numbers every 2 seconds, this function runs in a goroutine.
I need to pass its stdout printing to a variable and print it, but not one time, until it finish.
I need to have a some scanner in an infinite loop that will scan for the stdout and print it, once the function done the scanner will done too.
I tried to use this answer but it doesn't print anything.
This is what I tried to do:
package main
import (
"bufio"
"fmt"
"os"
"sync"
"time"
)
func print() {
for i := 0; i < 50; i++ {
time.Sleep(2 * time.Second)
fmt.Printf("hello number: %d\n", i)
}
}
func main() {
old := os.Stdout // keep backup of the real stdout
defer func() { os.Stdout = old }()
r, w, _ := os.Pipe()
os.Stdout = w
go print()
var wg sync.WaitGroup
c := make(chan struct{})
wg.Add(1)
defer wg.Done()
for {
<-c
scanner := bufio.NewScanner(r)
for scanner.Scan() {
m := scanner.Text()
fmt.Println("output: " + m)
}
}
c <- struct{}{}
wg.Wait()
fmt.Println("DONE")
}
I also tried to use io.Copy
to read the buffer like that but it didn't work too:
package main
import (
"bytes"
"fmt"
"io"
"os"
"time"
)
func print() {
for i := 0; i < 50; i++ {
time.Sleep(2 * time.Second)
fmt.Printf("hello number: %d\n", i)
}
}
// https://blog.kowalczyk.info/article/wOYk/advanced-command-execution-in-go-with-osexec.html
func main() {
old := os.Stdout // keep backup of the real stdout
defer func() { os.Stdout = old }()
r, w, _ := os.Pipe()
os.Stdout = w
go print()
fmt.Println("DONE 1")
outC := make(chan string)
for {
var buf bytes.Buffer
io.Copy(&buf, r)
outC <- buf.String()
out := <-outC
fmt.Println("output: " + out)
}
// back to normal state
w.Close()
fmt.Println("DONE")
}