在Go中执行shell命令

Chr*_*nch 38 shellexecute go

我想在Go中执行shell命令,并在程序中将结果输出作为字符串.我看到了Rosetta Code版本:

package main
import "fmt"
import "exec"

func main() {
  cmd, err := exec.Run("/bin/ls", []string{"/bin/ls"}, []string{}, "", exec.DevNull, exec.PassThrough, exec.PassThrough)
  if (err != nil) {
    fmt.Println(err)
    return
  }
  cmd.Close()
Run Code Online (Sandbox Code Playgroud)

但这并没有以我可以以编程方式访问的方式捕获实际标准或错误 - 那些仍然打印到常规stdout/stderr.我看到使用Pipe作为out或err可以帮助其他地方,但没有如何这样做的例子.有任何想法吗?

Lou*_*nco 102

包"exec" 有点改变了.以下代码对我有用.

package main

import "os/exec"
import . "fmt"

func main() {
    app := "echo"

    arg0 := "-e"
    arg1 := "Hello world"
    arg2 := "\n\tfrom"
    arg3 := "golang"

    cmd := exec.Command(app, arg0, arg1, arg2, arg3)
    stdout, err := cmd.Output()

    if err != nil {
        Println(err.Error())
        return
    }

    Print(string(stdout))
}
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助!

  • 现在导入必须像“os/exec”一样,我在 err.String() 中遇到了错误,但除此之外,它还可以工作。谢谢。 (2认同)
  • 有没有一种简单的方法将“stderr”与“stdout”分开。我看到`CombinedOutput()`,我看到更复杂的方法,但我想要的只是`out, errout, errcode = cmd.Output3()`。 (2认同)
  • @ cdunn2001,(1)#easy你可以在调用`cmd.Output()`之前设置`exec.Cmd.Stderr`由[你自己](http://pastebin.com/TCRLsUSW)或(2)#hard you将[你的功能](http://pastebin.com/wDNXP4Y3)添加到golang([$ GOROOT/src/pkg/os/exec/exec.go](http://golang.org/src/pkg/os/ exec/exec.go)),重新编译(cd $ GOROOT/src && ./make.bash),[测试它](http://pastebin.com/FTW2nsaX). (2认同)

jim*_*imt 7

这个答案并不代表 Go 标准库的当前状态。请查看@Lourenco对最新方法的回答


您的示例实际上并未从标准输出读取数据。这对我有用。

package main

import (
   "fmt"
   "exec"
   "os"
   "bytes"
   "io"
)

func main() {
    app := "/bin/ls"
    cmd, err := exec.Run(app, []string{app, "-l"}, nil, "", exec.DevNull, exec.Pipe, exec.Pipe)

    if (err != nil) {
       fmt.Fprintln(os.Stderr, err.String())
       return
    }

    var b bytes.Buffer
    io.Copy(&b, cmd.Stdout)
    fmt.Println(b.String())

    cmd.Close()
}
Run Code Online (Sandbox Code Playgroud)


typ*_*ris 7

提供的答案均不允许分开stdoutstderr因此我尝试另一个答案。

首先,如果您查看软件包中exec.Cmd类型的文档,则可以获得所需的所有信息os/exec。看这里:https//golang.org/pkg/os/exec/#Cmd

尤其是成员StdinStdoutStderr其中的任何成员io.Reader都可用于提供stdin新创建的进程的内容,而任何成员io.Writer均可用于使用stdoutstderr命令。

Shellout以下程序中的函数将运行您的命令,并将其输出和错误输出分别作为字符串传递给您:

package main

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

const ShellToUse = "bash"

func Shellout(command string) (error, string, string) {
    var stdout bytes.Buffer
    var stderr bytes.Buffer
    cmd := exec.Command(ShellToUse, "-c", command)
    cmd.Stdout = &stdout
    cmd.Stderr = &stderr
    err := cmd.Run()
    return err, stdout.String(), stderr.String()
}

func main() {
    err, out, errout := Shellout("ls -ltr")
    if err != nil {
        log.Printf("error: %v\n", err)
    }
    fmt.Println("--- stdout ---")
    fmt.Println(out)
    fmt.Println("--- stderr ---")
    fmt.Println(errout)
}
Run Code Online (Sandbox Code Playgroud)


小智 5

// ??exec ??shell= true ?????

func Cmd(cmd string, shell bool) []byte {

if shell {
    out, err := exec.Command("bash", "-c", cmd).Output()
    if err != nil {
        panic("some error found")
    }
    return out
} else {
    out, err := exec.Command(cmd).Output()
    if err != nil {
        panic("some error found")
    }
    return out

}
}
Run Code Online (Sandbox Code Playgroud)

你可以试试这个。