我试图在golang中运行一个命令,将阅读器提供给它的标准输入,返回它的标准输出,然后将其标准错误转换为错误消息。
我的问题是:我的代码工作得很好,当只管道到stdin和返回stdout。但是,当我尝试将stdout加载到缓冲区中时,如果stdout拥有比stdin更多的信息,则命令将挂起。我已经测试过了,它甚至适用于标准输出比标准输入大一个字节的情况。我已经被这个问题困了好几个小时了,在网上找不到任何解决办法。
相关代码如下:
var b bytes.Buffer
cmd := exec.Command(convCmd, convArgs...)
stdin, _ := cmd.StdinPipe()
stdout, _ := cmd.StdoutPipe()
cmd.Stderr = &b
go func() {
defer stdin.Close()
io.Copy(stdin, inStream)
}()
err = cmd.Start()
if b.String == "" {
err = nil
} else {
err = errors.New(b.String()
}
return stdout, err
这个问题快把我逼疯了,我唯一的猜测是这个命令正在等待stdin等于stdout的大小,但是它看起来很奇怪,只有当我试图将stderr加载到缓冲区中时才会这样做。
我确信这个问题还有其他几个解决方案,但我发现这个问题与将命令的标准输出直接管道化到函数的返回有关。
var b bytes.Buffer
cmd := exec.Command(convCmd, convArgs...)
stdin, err := cmd.StdinPipe()
if err != nil {
return nil, err
}
cmd.Stderr = &b
go func() {
defer stdin.Close()
io.Copy(stdin, n)
}()
// Run the command and buffer the output
byteSlice, err := cmd.Output()
stdout := bytes.NewReader(byteSlice)
// If the command exits non-zero status, return stderr as the error message
if err != nil {
err = errors.New(b.String())
}
return stdout, err
我没有直接使用阅读器,而是使用cmd.Output()来创建一个新的阅读器,现在命令有时间完成了。