go - Go 扫描缓冲区有时会挂起
问题描述
我使用以下代码可以正常工作,但是在某些情况下,进程卡住了,我看不到任何输出。示例此代码运行npm install
或mvn clean install
大部分时间运行良好,但有时它挂起并且您没有得到任何输出
func exec(stdout io.Reader, stderr io.Reader) (*bufio.Scanner, *bufio.Scanner) {
scanout := bufio.NewScanner(stdout)
scanerr := bufio.NewScanner(stderr)
scanout.Split(bufio.ScanRunes)
for scanout.Scan() {
fmt.Print(scanout.Text())
}
scanerr.Split(bufio.ScanRunes)
for scanerr.Scan() {
fmt.Print(scanerr.Text())
}
return scanout, scanerr
}
现在,如果我像以下那样更改顺序(首先是错误,其次是标准输出),当命令挂起时我会得到一些错误输出,但是我没有在线看到输出,当你运行命令时你会看到一些输出,完成后你会看到所有其余的部分 。您可以等待输出 2 分钟或更长时间,然后在流程结束时立即获得较长的输出。
如何解决我将能够在线获取输出并在进程挂起时获得一些反馈的问题?
func exec(stdout io.Reader, stderr io.Reader) (*bufio.Scanner, *bufio.Scanner) {
scanout := bufio.NewScanner(stdout)
scanerr := bufio.NewScanner(stderr)
scanout.Split(bufio.ScanRunes)
for scanout.Scan() {
fmt.Print(scanout.Text())
}
scanerr.Split(bufio.ScanRunes)
for scanerr.Scan() {
fmt.Print(scanerr.Text())
}
}
return scanout, scanerr
}
更新
应该是这样吗?
func exec(stdout io.Reader, stderr io.Reader) (*bufio.Scanner, *bufio.Scanner) {
scanout := bufio.NewScanner(stdout)
scanout.Split(bufio.ScanRunes)
go func() {
for scanout.Scan() {
fmt.Print(scanout.Text())
}
}()
go func() {
scanerr.Split(bufio.ScanRunes)
for scanerr.Scan() {
fmt.Print(scanerr.Text())
}
}()
}
解决方案
在第一种情况下,您正在从进程的标准输出中读取,直到进程结束。然后你从标准错误中读取。在第二种情况下,您首先从 err 读取,然后再读取。你应该读他们两个。要么使用 Cmd.CombinedOutput 来返回它们,要么启动两个 goroutine,一个从 stdin 读取,一个从 stderr 读取,直到流关闭。
scanout := bufio.NewScanner(stdout)
scanout.Split(bufio.ScanRunes)
go func() {
for scanout.Scan() {
fmt.Print(scanout.Text())
}
}()
推荐阅读
- node.js - 关于带有 express JS NodeJS 和 Mongo db 的异步函数的一些问题
- python - 如何在python中将字符串与行分开?
- vue.js - 更新属性时的Vue3插件更新输出
- ios - 构建离子应用程序以进行发布(XCode)的问题
- javascript - 如何检测不同格式的日期
- node.js - Nest JS 角色和基于权限的访问控制
- python - 如何在 Django Admin 中上传多个文件?
- java - 在获取 YYY-MM-DD 中的日期后,我想在 MM/DD/YYY 中添加日期
- javascript - 是否可以在使用 SpeechSynthesisUtterance API 时选择正在读取的 LETTER?
- mysql - sql numeric db 列如何与数字字符串值一起使用