猿问

如何捕获标准输出并显示进度

我有一个名为print()每 2 秒打印一次数字的函数,该函数在 goroutine 中运行。


我需要将其标准输出打印传递给一个变量并打印它,但不是一次,直到它完成。

我需要有一个无限循环中的扫描仪,它将扫描标准输出并打印它,一旦功能完成,扫描仪也将完成。


我试图使用这个答案,但它没有打印任何东西。

这就是我试图做的:


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")


}  


holdtom
浏览 99回答 1
1回答

饮歌长啸

可以print()作为“黑盒”运行并捕获其输出,尽管它有点棘手并且不适用于 Go Playground。package mainimport (&nbsp; &nbsp; "bufio"&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "os"&nbsp; &nbsp; "runtime"&nbsp; &nbsp; "time")func print() {&nbsp; &nbsp; for i := 0; i < 50; i++ {&nbsp; &nbsp; &nbsp; &nbsp; time.Sleep(100 * time.Millisecond)&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("hello number: %d\n", i)&nbsp; &nbsp; }}func main() {&nbsp; &nbsp; var ttyName string&nbsp; &nbsp; if runtime.GOOS == "windows" {&nbsp; &nbsp; fmt.Println("*** Using `con`")&nbsp; &nbsp; &nbsp; &nbsp; ttyName = "con"&nbsp; &nbsp; } else {&nbsp; &nbsp; fmt.Println("*** Using `/dev/tty`")&nbsp; &nbsp; &nbsp; &nbsp; ttyName = "/dev/tty"&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp; &nbsp; f, err := os.OpenFile(ttyName, os.O_WRONLY, 0644)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; panic(err)&nbsp; &nbsp; }&nbsp; &nbsp; defer f.Close()&nbsp; &nbsp; r, w, _ := os.Pipe()&nbsp; &nbsp; oldStdout := os.Stdout&nbsp; &nbsp; os.Stdout = w&nbsp; &nbsp; defer func() {&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; os.Stdout = oldStdout&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("*** DONE")&nbsp; &nbsp; }()&nbsp; &nbsp; fmt.Fprintln(f, "*** Stdout redirected")&nbsp; &nbsp; go func(){&nbsp; &nbsp; &nbsp; &nbsp;print()&nbsp; &nbsp; &nbsp; &nbsp;w.Close()&nbsp; &nbsp; &nbsp; &nbsp;r.Close()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; }()&nbsp; &nbsp; c := make(chan struct{})&nbsp; &nbsp; go func(){c <- struct{}{}}()&nbsp; &nbsp; defer close(c)&nbsp; &nbsp; <-c&nbsp; &nbsp; scanner := bufio.NewScanner(r)&nbsp; &nbsp; for scanner.Scan() {&nbsp; &nbsp; &nbsp; &nbsp; m := scanner.Text()&nbsp; &nbsp; &nbsp; &nbsp; fmt.Fprintln(f, "output: " + m)&nbsp; &nbsp; }}
随时随地看视频慕课网APP

相关分类

Go
我要回答