7

我需要找到一种从 io.ReadCloser 对象中读取一行的方法,或者找到一种在“结束行”符号上拆分字节数组的方法。但是我不知道结束线符号,我找不到它。

我的应用程序执行了一个 php 脚本,需要从脚本中获取实时输出,并在得到它时用它做“某事”。

这是我的一小段代码:

cmd := exec.Command(prog, args)   
/* cmd := exec.Command("ls")*/
out, err := cmd.StdoutPipe()
if err != nil {
  fmt.Println(err)
}
err = cmd.Start()
if err != nil {
  fmt.Println(err)
}

out在此之后,我在 go 例程中监视缓冲区。我尝试了2种方法。
1) nr, er := out.Read(buf)wherebuf是一个字节数组。这里的问题是我需要为每个新行制动数组
2)我的第二个选项是创建一个新的 bufio.reader 如果我执行类似的命令,它运行良好,我逐行获取输出,但是如果我执行一个 php 脚本它立即得到一个 End Of File 错误并退出(我猜这是因为 php 的延迟输出)
r := bufio.NewReader(out)
line,_,e := r.ReadLine()

ls

编辑:我的问题是我在 go 例程中创建 bufio.Reader 而如果我在StdoutPipe()minikomi 建议之后立即执行它,它工作正常

4

2 回答 2

9

您可以使用 bufio 创建一个阅读器,然后阅读直到下一个换行符(注意,单引号表示字符!):

stdout, err := cmd.StdoutPipe()
rd := bufio.NewReader(stdout)
if err := cmd.Start(); err != nil {
    log.Fatal("Buffer Error:", err)
}

for {
    str, err := rd.ReadString('\n')
    if err != nil {
        log.Fatal("Read Error:", err)
        return
    }
    fmt.Println(str)
}

如果您试图在 goroutine 中读取阅读器,而没有任何东西可以停止脚本,它将退出。

于 2012-10-25T10:55:48.550 回答
2

另一种选择是bufio.NewScanner

package main

import (
   "bufio"
   "os/exec"
)

func main() {
   cmd := exec.Command("go", "env")
   out, err := cmd.StdoutPipe()
   if err != nil {
      panic(err)
   }
   buf := bufio.NewScanner(out)
   cmd.Start()
   defer cmd.Wait()
   for buf.Scan() {
      println(buf.Text())
   }
}

https://golang.org/pkg/bufio#NewScanner

于 2021-06-04T20:46:22.560 回答