默认情况下,Go命令的输出会发送到标准输出(stdout)。

huangapple go评论82阅读模式
英文:

Go command output by default to stdout?

问题

我开始学习并尝试使用Go语言来制作一些更复杂的控制台/命令行工具,而不是使用shell或Python。我想执行命令并显示输出结果。我已经找到了如下的打印输出结果的方法:

out, err := exec.Command("pwd").Output()
print(string(out))

有没有一种方法可以执行命令并将其默认输出到标准输出(stdout),就像shell脚本一样,还是我需要编写一个辅助函数来实现这个功能?

更新:在安装了IntelliJ和Go插件之后,我在Go源代码中查找了一下,同意目前没有办法在不使用辅助方法的情况下实现这个功能。

根据exec.go源代码中的注释,无法重用Cmd对象:

// 在调用Run、Output或CombinedOutput方法之后,Cmd对象无法被重用。

我已经将stdout选项整合到了自己的辅助函数中,还包括其他选项,比如shell集成。如果有用的话,我会尝试将其开源。Go的第一天很有趣。

英文:

I started learning and playing around with Go to see what it is like to make some more complex console/cli type tools instead of using shells or Python. I want to execute commands and display the output. I figured out how to print the output like this:

out, err := exec.Command("pwd").Output()
print(string(out))

Is there a way to execute the commands and have it default to stdout like a shell script, or do I need to make a helper function for this?

Update: After getting IntelliJ and the Go plugin, I poked around in the Go source and agree there is currently no way to do with without a helper method.

It is not possible to reuse a Cmd object as per this comment in the exec.go source code:

// A Cmd cannot be reused after calling its Run, Output or CombinedOutput
// methods.

I did incorporate the stdout option into my own helper, including other options like shell integration. I will try turn that into open source if I can make it useful. An interesting first day of Go.

答案1

得分: 3

解决方案

实际上,这很简单。你可以将命令的标准输出设置为os.Stdout,就完成了:

package main

import (
  "os"
  "os/exec"
)

func main() {

  cmd := exec.Command("pwd")

  cmd.Stdout = os.Stdout

  err := cmd.Run()

  if err != nil {
    panic(err)
  }
}

这里发生了什么?

默认情况下,如果未将cmd.Stdout设置为另一个io.Writer,命令的输出将存储在bytes.Buffer中。调用cmd.Output()会运行命令并将输出保存到该缓冲区中。

由于os.Stdout实现了io.Writer接口,我们只需将cmd.Stdout设置为os.Stdout。现在,当调用.Run()时,命令的输出将被写入在cmd.Stdout中定义的io.Writer,也就是os.Stdout,然后输出将写入到shell中。

编辑:根据评论,如果所有命令都应写入os.Stdout,那么当然无法阻止一些辅助程序。我会这样做:

package main 

import (
 "os"
 "os/exec"
)

func CmdToStdout(c string) (err error){
  cmd := exec.Command(c)
  cmd.Stdout = os.Stdout
  err = cmd.Run()
  return
}

func main() {

  err := CmdToStdout("pwd")
  if err != nil {
    panic(err)
  }
}
英文:

The solution

Actually, it is pretty easy. You can set the stdout of the command to os.Stdout and Bob's your uncle:

<!-- language-all: lang-go -->

package main

import (
  &quot;os&quot;
  &quot;os/exec&quot;
)

func main() {

  cmd := exec.Command(&quot;pwd&quot;)

  cmd.Stdout = os.Stdout

  err := cmd.Run()

  if err != nil {
    panic(err)
  }
}

What's happening here?

By default, the output of a command is stored in a bytes.Buffer if cmd.Stdout is not set to another io.Writer. The call of cmd.Output() then runs the command and saves the output to said buffer.

Since os.Stdout implements io.Writer interface, we simply set cmd.Stdout to be os.Stdout. Now when .Run() is called, the output of the command gets written to the io.Writer defined in cmd.Stdout, which happens to be os.Stdout and the output gets written in the shell.

EDIT: As per comment, if all commands should write to os.Stdout, there of course is no way to prevent some helper. I'd do it like this:

package main 

import (
 &quot;os&quot;
 &quot;os/exec&quot;
)

func CmdToStdout( c string ) (err error){
  cmd := exec.Command(c)
  cmd.Stdout = os.Stdout
  err = cmd.Run()
  return
}

func main() {

  err := CmdToStdout(&quot;pwd&quot;)
  if err != nil {
    panic(err)
  }
}

答案2

得分: 1

你需要创建一个助手,如果你经常需要这样做的话(而且5行代码看起来太多了)。根据文档,这是一种推荐的方式:

package main

import (
	"fmt"
	"log"
	"os/exec"
)

func main() {
	out, err := exec.Command("date").Output()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("日期是:%s\n", out)
}
英文:

You have to create a helper if you need this often (and 5 lines looks too much). Based on the documentation this is a recommended way:

package main

import (
	&quot;fmt&quot;
	&quot;log&quot;
	&quot;os/exec&quot;
)

func main() {
	out, err := exec.Command(&quot;date&quot;).Output()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf(&quot;The date is %s\n&quot;, out)
}

huangapple
  • 本文由 发表于 2015年11月28日 14:42:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/33968531.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定