如何在Go中获得系统命令的输出?

mar*_*ter 48 go

假设我想在go程序中运行'ls',并将结果存储在一个字符串中.似乎有一些命令在exec和os包中派生进程,但它们需要stdout等的文件参数.有没有办法将输出作为字符串?

Fat*_*lan 186

现在有一种更简单的方法:

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)
}
Run Code Online (Sandbox Code Playgroud)

out标准输出在哪里.它采用的格式[]byte,但您可以通过以下方式轻松将其更改为字符串:

string(out)
Run Code Online (Sandbox Code Playgroud)

您也可以使用CombinedOutput() 而不是Output()返回标准输出和标准错误.

  • 这很可能是现在接受的答案.接受的答案甚至不再编译. (11认同)

Tra*_*der 17

要将stdout和stderr都放入单独的字符串中,可以使用字节缓冲区,如下所示:

cmd := exec.Command("date")
var outb, errb bytes.Buffer
cmd.Stdout = &outb
cmd.Stderr = &errb
err := cmd.Run()
if err != nil {
    log.Fatal(err)
}
fmt.Println("out:", outb.String(), "err:", errb.String())
Run Code Online (Sandbox Code Playgroud)


lca*_*pra 6

我在最新版本的 GO (~1.11) 中使用了它

// CmdExec Execute a command
func CmdExec(args ...string) (string, error) {

    baseCmd := args[0]
    cmdArgs := args[1:]

    log.Debugf("Exec: %v", args)

    cmd := exec.Command(baseCmd, cmdArgs...)
    out, err := cmd.Output()
    if err != nil {
        return "", err
    }

    return string(out), nil
}

// Usage:
// out, err := CmdExec("ls", "/home")
Run Code Online (Sandbox Code Playgroud)


Ina*_*Xia 6

cmd := exec.Command("ls", "-al")
output, _ := cmd.CombinedOutput()
fmt.Println(string(output))
Run Code Online (Sandbox Code Playgroud)

或者

cmd := exec.Command(name, arg...)
stdout, err := cmd.StdoutPipe()
cmd.Stderr = cmd.Stdout
if err != nil {
    return err
}
if err = cmd.Start(); err != nil {
    return err
}
for {
    tmp := make([]byte, 1024)
    _, err := stdout.Read(tmp)
    fmt.Print(string(tmp))
    if err != nil {
        break
    }
}
Run Code Online (Sandbox Code Playgroud)


Ran*_*ku' 0

编辑:这个答案已经过时了。请参阅下面Fatih Arslan 的回答


通过将Pipe指定为 stdout(如果需要,也可以指定 stderr)来使用exec.Run 。它将返回 cmd,其中在 Stdout(和 Stderr)字段中包含一个os.File 。然后您可以使用例如ioutil.ReadAll来读取它。

例子:

package main

import (
    "exec";
    "io/ioutil";
)

func main() {
    if cmd, e := exec.Run("/bin/ls", nil, nil, exec.DevNull, exec.Pipe, exec.MergeWithStdout); e == nil {
        b, _ := ioutil.ReadAll(cmd.Stdout)
        println("output: " + string(b))
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为“exec”包不再存在。我必须使用下面 Fatih 列出的“os/exec”。 (19认同)
  • 否决原因:这个答案可能已经过时了,希望人们知道它。`exec` 包不再存在,据我所知,`ioutil.ReadAll()` 不再接受 `cmd.Stdout` 但接受 `cmd.Stdin`,因此几乎所有关于这个答案的内容都是错误且过时的。 (7认同)