在Go中redirectsubprocess的stdoutpipe道
我正在用Go编写一个程序,执行一个像程序一样的服务器(也是Go)。 现在我想要在terminal窗口中开始父程序的子程序的标准输出。 一种方法是使用cmd.Output()
函数,但是只有在进程退出后才会打印stdout。 (这是一个问题,因为这个类似于服务器的程序运行很长时间,我想读取日志输出)
variablesout
是type io.ReadCloser
,我不知道该怎么做才能完成我的任务,在这个主题上我找不到有用的东西。
func main() { cmd := exec.Command("/path/to/my/child/program") out, err := cmd.StdoutPipe() if err != nil { fmt.Println(err) } err = cmd.Start() if err != nil { fmt.Println(err) } //fmt.Println(out) cmd.Wait() }
解释代码:取消注释Println
函数来获取代码进行编译,我知道Println(out io.ReadCloser)
不是一个有意义的函数。
(它产生输出&{3 |0 <nil> 0}
)这两行只是需要编译代码。
现在我想要在terminal窗口中开始父程序的子程序的标准输出。
没有必要弄乱pipe道或门厅,这个很容易。
func main() { // Replace `ls` (and its arguments) with something more interesting cmd := exec.Command("ls", "-l") cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Run() }
我相信如果你导入io
和os
并replace它:
//fmt.Println(out)
有了这个:
go io.Copy(os.Stdout, out)
(请参阅io.Copy
和os.Stdout
文档),它会做你想做的。 (免责声明:未经testing。)
顺便说一句,你可能也想捕获标准错误,通过使用与标准输出相同的方法,但使用cmd.StderrPipe
和os.Stderr
。
对于那些在循环中不需要这个的人,但是希望命令输出回显到terminal,而不需要使用cmd.Wait()
阻塞其他语句:
package main import ( "fmt" "io" "log" "os" "os/exec" ) func checkError(err error) { if err != nil { log.Fatalf("Error: %s", err) } } func main() { // Replace `ls` (and its arguments) with something more interesting cmd := exec.Command("ls", "-l") // Create stdout, stderr streams of type io.Reader stdout, err := cmd.StdoutPipe() checkError(err) stderr, err := cmd.StderrPipe() checkError(err) // Start command err = cmd.Start() checkError(err) // Don't let main() exit before our command has finished running defer cmd.Wait() // Doesn't block // Non-blockingly echo command output to terminal go io.Copy(os.Stdout, stdout) go io.Copy(os.Stderr, stderr) // I love Go's trivial concurrency :-D fmt.Printf("Do other stuff here! No need to wait.\n\n") }