gpt4 book ai didi

go - 从 `exec.Cmd` 中获取 "real-time"的输出

转载 作者:IT王子 更新时间:2023-10-29 01:39:33 25 4
gpt4 key购买 nike

这个问题类似于Golang - Copy Exec output to Log除了它与 exec 命令输出的缓冲有关。

我有以下测试程序:

package main

import (
"fmt"
"log"
"os/exec"
)

func main() {
cmd := exec.Command("python", "inf_loop.py")
var out outstream
cmd.Stdout = out
if err := cmd.Start(); err != nil {
log.Fatal(err)
}
fmt.Println(cmd.Wait())
}

type outstream struct{}

func (out outstream) Write(p []byte) (int, error) {
fmt.Println(string(p))
return len(p), nil
}
上面提到的

inf_loop.py 只包含:

print "hello"
while True:
pass

go 程序在我运行时挂起并且不输出任何内容,但是如果我使用 os.Stdout 而不是 out 那么它会在它之前输出“hello”挂起。为什么两个 io.Writer 之间存在差异,如何解决?

一些更多的诊断信息:

  • 当循环从 inf_loop.py 中移除时,两个程序都会输出“hello”,正如预期的那样。
  • 当使用 yes 作为程序而不是 python 脚本并在 outstream.Write 中输出 len(p) 时,就会有输出,并且输出通常是 16384 或 32768。这向我表明这是一个缓冲问题,正如我最初预期的那样,但我仍然不明白为什么 outstream 结构被缓冲阻塞但是 os.Stdout 不是。一种可能是该行为是 execio.Writer 直接传递给 os.StartProcess 的方式的结果,如果它是 os.File(详见 source),否则它会在进程和 io.Writer 之间创建一个 os.Pipe(),并且此管道可能导致缓冲。但是,os.Pipe() 的操作和可能的缓冲级别太低,我无法研究。

最佳答案

Python 默认缓冲标准输出。试试这个程序:

import sys
print "hello"
sys.stdout.flush()
while True:
pass

或者使用无缓冲的 stdout 和 stderr 运行 Python:

cmd := exec.Command("python", "-u", "foo.py")

注意 -u 标志。

当使用 cmd.Stout = os.Stdout 时,您会看到不同的结果,因为当 stdout 是终端时,Python 使用行缓冲。

关于go - 从 `exec.Cmd` 中获取 "real-time"的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31015754/

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