英文:
How do you get the output of a system command in Go?
问题
假设我想在Go程序中运行'ls'命令,并将结果存储在一个字符串中。在exec和os包中似乎有一些用于分叉进程的命令,但它们需要stdout等的文件参数。有没有办法将输出作为字符串获取?
英文:
Let's say I want to run 'ls' in a go program, and store the results in a string. There seems to be a few commands to fork processes in the exec and os packages, but they require file arguments for stdout, etc. Is there a way to get the output as a string?
答案1
得分: 431
现在有一种更简单的方法:
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)
}
其中 out
是标准输出。它的格式是 []byte
,但你可以很容易地将其转换为字符串:
string(out)
你也可以使用 CombinedOutput()
替代 Output()
,它会返回标准输出和标准错误。
英文:
There is an easier way now:
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)
}
Where out
is the standard output. It's in the format []byte
, but you can change it to string easily with:
string(out)
You can also use CombinedOutput()
instead of Output()
which returns standard output and standard error.
答案2
得分: 60
要将标准输出和标准错误输出分别存储到不同的字符串中,您可以使用字节缓冲区,代码如下:
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())
英文:
To get both stdout and stderr into separate strings, you can use byte buffers like so:
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())
答案3
得分: 14
cmd := exec.Command("ls", "-al")
output, _ := cmd.CombinedOutput()
fmt.Println(string(output))
or
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
}
}
英文:
cmd := exec.Command("ls", "-al")
output, _ := cmd.CombinedOutput()
fmt.Println(string(output))
or
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
}
}
答案4
得分: 6
我使用了最近版本的GO(~1.11)
// CmdExec 执行一个命令
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
}
// 使用方法:
// out, err := CmdExec("ls", "/home")
英文:
I used this with a recent version of 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")
答案5
得分: 4
两种选择,取决于您喜欢的范例:
答案6
得分: 3
使用exec.Run,将Pipe传递给stdout。从返回的管道中读取。
英文:
Use exec.Run, passing Pipe for stdout. Read from the pipe that it returns.
答案7
得分: 3
如果你想要string
输出,strings.Builder
比bytes.Buffer
更高效1:
package main
import (
"os/exec"
"strings"
)
func main() {
c, b := exec.Command("go", "version"), new(strings.Builder)
c.Stdout = b
c.Run()
print(b.String())
}
英文:
If you are wanting string
output, strings.Builder
is more efficient 1 than
bytes.Buffer
:
package main
import (
"os/exec"
"strings"
)
func main() {
c, b := exec.Command("go", "version"), new(strings.Builder)
c.Stdout = b
c.Run()
print(b.String())
}
答案8
得分: 0
编辑: 这个答案已经过时了。请参考下面的 Fatih Arslan 的答案。
使用 exec.Run,将 Pipe 指定为 stdout(如果需要,也可以指定为 stderr)。它会返回 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))
}
}
英文:
Edit: This answer is obsolete. Please see Fatih Arslan's answer below.
Use exec.Run by specifying Pipe as the stdout (and stderr if you want). It will return cmd, which contains an os.File in the Stdout (and Stderr) fields. Then you can read it using for example ioutil.ReadAll.
Example:
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))
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论