gpt4 book ai didi

go - Reader 从不读取 `StdoutPipe`

转载 作者:IT王子 更新时间:2023-10-29 02:06:56 26 4
gpt4 key购买 nike

我正在尝试从一个长时间运行的(阻塞/类 shell)命令中读取标准输出,最终目标是创建一个 Go 可以与之交互的边车进程。

我有以下 MCVE:

func main() {
var err error
// Build the long-running command
args := []string{"-i0", "-o0", "-e0", "/usr/local/bin/ipython"}
cmd := exec.Command("stdbuf", args...)

// Keep the stdin file descriptor open
// Spawned command should block waiting for input
_, err = cmd.StdinPipe()
if err != nil {
panic(err)
}

// Setup pipe of `Reader` type
var stdoutBuf []byte
stdout, err := cmd.StdoutPipe()
if err != nil {
panic(err)
}

// Start the command
if err = cmd.Start(); err != nil {
panic(err)
}

go func() {
for {
// Asynchronously continue reading from stdout
n, err := stdout.Read(stdoutBuf)
fmt.Println(n)
if err != nil {
panic(err)
}
fmt.Println(stdoutBuf)
time.Sleep(time.Millisecond * 2000)
}
}()

// Block forever
if err = cmd.Wait(); err != nil {
panic(err)
}
}

从语义上讲,这种方法似乎可行。我希望 stdout.Read 会返回一些东西(ipython shell 序言),但 n 始终为 0。

  1. 为什么此示例中的 Reader.Read 从未读取任何内容?
  2. 有点相关的问题:如果没有任何内容可读,有没有什么方法可以阻止我读取 StdoutPipe

我不认为进程本身有任何问题(这会导致读取无效的文件描述符)因为Start 不会panic 而且它看起来像cmd.Wait 永远阻塞。

最佳答案

Why does Reader.Read in this example never read anything?

因为您正在读取大小为 0 的缓冲区,这是 var stdoutBuf []byte 创建的。相反,使用类似的东西:

stdoutBuf := make([]byte, 4096)

您可能还想使用 bufio .

Somewhat related question: is there a way I can block on reading StdoutPipe if there is nothing to be read?

stdout.Read 已经阻塞,这是 io.Reader 的典型(尽管不是必需的) :

If some data is available but not len(p) bytes, Read conventionally returns what is available instead of waiting for more. [...] Implementations of Read are discouraged from returning a zero byte count with a nil error, except when len(p) == 0.

关于go - Reader 从不读取 `StdoutPipe`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55987455/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com