我正在Go中编写一个程序来执行类似程序的服务器(也是Go)。现在我想在我启动父程序的终端窗口中输入子程序的标准输出。一种方法是使用cmd.Output()
函数,但只有在进程退出后才打印stdout。 (这是一个问题,因为这个类似服务器的程序运行了很长时间,我想读取日志输出)
变量out
属于type io.ReadCloser
,我不知道应该怎么做才能完成我的任务,而且我在网上找不到任何有用的信息。< / p>
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}
)只需要这两行来获取要编译的代码。
答案 0 :(得分:187)
现在我希望在终端中拥有子程序的标准输出 我启动父程序的窗口。
无需弄乱管道或goroutines,这个很容易。
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()
}
答案 1 :(得分:17)
我相信如果你导入io
和os
并替换它:
//fmt.Println(out)
用这个:
go io.Copy(os.Stdout, out)
(参见文档for io.Copy
和for os.Stdout
),它会做你想要的。 (免责声明:未经测试。)
顺便说一句,您可能也希望通过使用与标准输出相同的方法捕获标准错误,但使用cmd.StderrPipe
和os.Stderr
。
答案 2 :(得分:14)
对于那些在循环中不需要它的人,但是希望命令输出回显到终端而不会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")
}