【发布时间】:2018-04-03 16:47:28
【问题描述】:
我正面临一个奇怪的 golang 问题。下面的代码将澄清:
package main
import (
"os/exec"
"io"
"fmt"
"os"
)
var (
pw io.WriteCloser
pr io.ReadCloser
)
func main() {
term := exec.Command("/bin/sh")
// Get stdin writer pipe
pw, _ = term.StdinPipe()
pr, _ = term.StdoutPipe()
term.Start()
run("cd ~")
pwd := run("pwd");
// Do something with pwd output
...
term.Wait()
}
func run(c string) string {
io.WriteString(pw, fmt.Sprintln(c))
buf := make([]byte, 32 * 1024)
pr.Read(buf)
return string(buf)
}
我想在 shell 环境中运行一些命令并读取它们的输出。写入/运行命令没有问题,但阅读时似乎有一些限制:
- 您无法知道命令是否不输出任何内容;
- 无法检查 stdout 是否已准备好读取。
pr.Read(dest) 方法将阻塞代码流,直到从标准输出中读取某些内容。如前所述,目标是顺序读取(不使用 go 例程和/或无限循环)。这意味着如果我们发送一个cd 命令,函数的终点永远不会到达。
在标准输出文件描述符上通过unix.SetNonblock 设置非块标志似乎可以解决上述问题,但您无法事先知道它是否准备好,并且从@987654325 返回“资源暂时不可用”的错误@调用。
【问题讨论】:
-
你为什么不直接运行你真正想运行的命令,而不是尝试启动一个shell?
-
不使用goroutine的原因是什么?
-
@MichaelHampton 不幸的是,一旦您终止进程(shell),您将无法检索当前的工作路径,并且 shell 会以二进制路径作为工作路径重新启动。
-
你说的功能是什么?该示例显示了一个函数
main。在任何情况下,使用 goroutines 都不会阻止子进程 stdout 的顺序读取。 -
整个方法没有任何意义。你到底想做什么?