英文:
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 (
"os"
"os/exec"
)
func main() {
cmd := exec.Command("pwd")
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 (
"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)
}
}
答案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 (
"fmt"
"log"
"os/exec"
)
func main() {
out, err := exec.Command("date").Output()
if err != nil {
log.Fatal(err)
}
fmt.Printf("The date is %s\n", out)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论