[英]Running external python in Golang, Catching continuous exec.Command Stdout
所以我的 go 脚本会像这样调用外部 python
cmd = exec.Command("python","game.py")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
go func(){
err := cmd.Run()
if err != nil{
panic(err)
}
}()
它同时运行我的 python 脚本,这太棒了。 但是现在的问题是,我的python脚本会无限运行,并且会不时打印出一些信息。 我想“捕捉”这些标准输出并在我的 golang 终端上打印出来。 如何同时执行(无需等待我的 python 脚本退出)?
使用cmd.Start()
和cmd.Wait()
而不是cmd.Run()
。
https://golang.org/pkg/os/exec/#Cmd.Run
Run 启动指定的命令并等待它完成。
Start 启动指定的命令,但不等待它完成。
Wait 等待命令退出。 它必须由 Start 启动。
如果您想同时捕获 stdout/stderr,请使用cmd.StdoutPipe()
/ cmd.StderrPipe()
并通过bufio.NewScanner()
读取
package main
import (
"bufio"
"fmt"
"io"
"os/exec"
)
func main() {
cmd := exec.Command("python", "game.py")
stdout, err := cmd.StdoutPipe()
if err != nil {
panic(err)
}
stderr, err := cmd.StderrPipe()
if err != nil {
panic(err)
}
err = cmd.Start()
if err != nil {
panic(err)
}
go copyOutput(stdout)
go copyOutput(stderr)
cmd.Wait()
}
func copyOutput(r io.Reader) {
scanner := bufio.NewScanner(r)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
}
以下是用于重现实时输出的示例 Python 代码。 标准输出可以在 Python 中缓冲。 可能需要显式刷新。
import time
import sys
while True:
print "Hello"
sys.stdout.flush()
time.sleep(1)
您可以使用添加标志-u
来关闭缓冲,
cmd := exec.Command("python", "-u", "game.py")
如果要同时捕获 stdout 和 stderr,确实需要使用cmd.StdoutPipe()
、 cmd.StderrPipe()
、 cmd.Start()
和cmd.Wait()
。
但如文档中所述( https://pkg.go.dev/os/exec#Cmd.StdoutPipe ):
因此,在管道的所有读取完成之前调用 Wait 是不正确的。
在调用cmd.Wait()
之前,您需要等待 goroutine 完成(请参阅以下线程: https ://github.com/golang/go/issues/38268)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.