从 os.stdout 读取

Read from os.stdout

提问人:Yangyang 提问时间:10/12/2022 最后编辑:Jamiu S.Yangyang 更新时间:10/12/2022 访问量:366

问:

我想将日志信息发送到套接字,为此,我需要首先捕获os.stdout。我知道我可以使用os.pipe重定向os.stdout。但是有没有办法我直接从os.stdout使用bufio读取。NewReader 或 bufio。新扫描仪?

func Start() {
   //dataChan := make(chan string)

   outC := make(chan string, 3)
   defer close(outC)
   conn, err := net.Dial("tcp", "localhost:9090")

   if err != nil {
       log.Fatal(err)
   }

   fmt.Println("first line!")
   fmt.Println("second line!")
   fmt.Println("third line!")
   // write to channel
   go func() {
       scanner := bufio.NewScanner(os.Stdout)
       for scanner.Scan() {
           outC <- scanner.Text() + "\n"
           err = scanner.Err()

           if err != nil {
               log.Fatal(err)
           }
       }
   }()

   // read from channel and print to connection
   go func() {
       out := <-outC

       for {
           conn.Write([]byte(out + "\n"))
       }

   }()

}
Go 日志记录 IO 缓冲区

评论


答:

0赞 zangw 10/12/2022 #1

你可以通过 os 读取 stdout。管

    old := os.Stdout
    r, w, _ := os.Pipe()
    os.Stdout = w

    go func() {
        var buf bytes.Buffer
        io.Copy(&buf, r)
        outC <- buf.String()
    }()

    fmt.Println("first line!")
    fmt.Println("second line!")
    fmt.Println("third line!")

    w.Close()
    os.Stdout = old // restore stdout

    for {
        select {
        case out := <-outC:
            conn.Write([]byte("read " + out + "\n"))
        }
    }

评论

0赞 Yangyang 10/12/2022
为什么我不能直接读取操作系统。Stdout?
0赞 zangw 10/12/2022
@Yangyang,并非每个文件都是可读或可写的。 通常是无法读回的文件。它可以是可写的。Stdout
0赞 Yangyang 10/12/2022
谢谢。这也是我心目中的答案。只是 go 编译器没有抱怨我正在从只写文件中读取。有点奇怪。
0赞 colm.anseo 10/12/2022
仅供参考:如果在并发情况下使用,则此处存在潜在的竞争条件捕获/恢复。os.Stdout
0赞 Yangyang 10/13/2022
@colm.anseo 谢谢。有没有办法避免它。我想在每个 go 例程中进行重定向,然后读取器和写入器都将是局部变量。所以操作系统。Stdout 会在 go 例程中被重定向,还是比赛条件?