Je cherche à exécuter une commande Shell dans Go et à obtenir le résultat obtenu sous forme de chaîne dans mon programme. J'ai vu le Rosetta Code version:
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()
Mais cela ne capture pas la sortie standard standard ni les erreurs commises de manière programmable - celles-ci sont toujours imprimées sur la sortie standard/stderr normale. J'ai vu qu'utiliser Pipe comme solution de rechange ou d'erreur pourrait aider ailleurs, mais je n'ai pas d'exemple de la façon de le faire Des idées?
Cette réponse ne représente pas l'état actuel de la bibliothèque standard Go. S'il vous plaît jeter un oeil à la réponse de @ Lourenco pour une méthode à jour!
Votre exemple ne lit pas les données de stdout. Cela fonctionne pour moi.
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()
}
Le paquet "exec" était a légèrement changé . Le code suivant a fonctionné pour moi.
package main
import "os/exec"
func main() {
app := "echo"
//app := "buah"
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))
}
J'espère que ça aide!
Aucune des réponses fournies ne permet de séparer stdout
et stderr
alors j'essaie une autre réponse.
Vous obtenez d’abord toutes les informations dont vous avez besoin, si vous consultez la documentation du type exec.Cmd
dans le package os/exec
. Regardez ici: https://golang.org/pkg/os/exec/#Cmd
En particulier, les membres Stdin
et Stdout
, Stderr
où tout io.Reader
peut être utilisé pour alimenter stdin
de votre processus nouvellement créé et tout io.Writer
utilisé pour consommer stdout
et stderr
de votre commande.
La fonction Shellout
dans le programme suivant lancera votre commande et vous remettra sa sortie et sa sortie d'erreur séparément sous forme de chaînes:
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)
}
// 封装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
}
}
vous pouvez essayer ceci.
Voici une fonction simple qui exécutera votre commande et capturera l’erreur, stdout et stderr à inspecter. Vous pouvez facilement voir tout ce qui pourrait mal tourner ou vous être signalé.
// RunCMD is a simple wrapper around terminal commands
func RunCMD(path string, args []string, debug bool) (out string, err error) {
cmd := exec.Command(path, args...)
var b []byte
b, err = cmd.CombinedOutput()
out = string(b)
if debug {
fmt.Println(strings.Join(cmd.Args[:], " "))
if err != nil {
fmt.Println("RunCMD ERROR")
fmt.Println(out)
}
}
return
}
Vous pouvez l'utiliser comme ceci (Conversion d'un fichier multimédia):
args := []string{"-y", "-i", "movie.mp4", "movie_audio.mp3", "INVALID-ARG!"}
output, err := RunCMD("ffmpeg", args, true)
if err != nil {
fmt.Println("Error:", output)
} else {
fmt.Println("Result:", output)
}
J'ai utilisé cela avec Go 1.2-1.7