Goexec命令教程展示了如何在Golang中执行shell命令和程序。
Run函数启动指定的命令并等待它完成,而Start函数启动指定的命令但不等待它完成;我们需要使用Wait和Start。
去操作系统/执行
os/exec包运行外部命令。它包装了os.StartProcess,以便更轻松地重新映射标准输入和标准输出、使用管道连接I/O以及进行其他调整。
$ go version go version go1.18.1 linux/amd64
我们使用Go版本1.18。
执行程序
Run启动指定的命令并等待它完成。
package main
import (
"log"
"os/exec"
)
func main() {
cmd := exec.Command("firefox")
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
}
在代码示例中,我们执行Firefox浏览器。
执行命令
Command返回Cmd结构以使用给定的参数执行指定的程序。第一个参数是要运行的程序;其他参数是程序的参数。
package main
import (
"bytes"
"fmt"
"log"
"os/exec"
"strings"
)
func main() {
cmd := exec.Command("tr", "a-z", "A-Z")
cmd.Stdin = strings.NewReader("and old falcon")
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
fmt.Printf("translated phrase: %q\n", out.String())
}
在代码示例中,我们通过tr命令转换输入。
cmd := exec.Command("tr", "a-z", "A-Z")
tr标准Linux命令转换、压缩和/或删除标准输入中的字符,写入标准输出。在我们的例子中,我们将小写字母转换为大写字母。
cmd.Stdin = strings.NewReader("and old falcon")
通过Stdin字段,我们将字符串作为输入传递给命令。
var out bytes.Buffer cmd.Stdout = &out
程序的输出将写入字节缓冲区。
$ go run command.go translated phrase: "AND OLD FALCON"
执行带多个参数的命令
我们可以将多个参数传递给exec.Command。
package main
import (
"fmt"
"os/exec"
)
func main() {
prg := "echo"
arg1 := "there"
arg2 := "are three"
arg3 := "falcons"
cmd := exec.Command(prg, arg1, arg2, arg3)
stdout, err := cmd.Output()
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Print(string(stdout))
}
该示例使用三个参数运行echo命令。
$ go run multiple_args.go there are three falcons
goexec命令捕获输出
Output运行命令并返回其标准输出。
package main
import (
"fmt"
"log"
"os/exec"
)
func main() {
out, err := exec.Command("ls", "-l").Output()
if err != nil {
log.Fatal(err)
}
fmt.Println(string(out))
}
该示例捕获ls命令的输出并将其打印出来。
转到cmd.StdinPipe
管道允许我们将一个命令的输出发送到另一个。StdinPipe返回一个管道,该管道将在命令启动时连接到命令的标准输入。
package main
import (
"fmt"
"io"
"log"
"os/exec"
)
func main() {
cmd := exec.Command("cat")
stdin, err := cmd.StdinPipe()
if err != nil {
log.Fatal(err)
}
go func() {
defer stdin.Close()
io.WriteString(stdin, "an old falcon")
}()
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", out)
}
在代码示例中,我们将字符串写入goroutine中的标准输入。
cmd := exec.Command("cat")
cat命令将给定的文件连接到标准输出。当没有给定文件或带有-时,该命令读取标准输入并将其打印到标准输出。
stdin, err := cmd.StdinPipe()
我们得到了cat命令的标准输入管道。
go func() {
defer stdin.Close()
io.WriteString(stdin, "an old falcon")
}()
在goroutine中,我们将一个字符串写入标准输入管道。
$ go run stdinpipe.go an old falcon
转到cmd.StdoutPipe
StdoutPipe返回一个管道,该管道将在命令启动时连接到命令的标准输出。
package main
import (
"fmt"
"io/ioutil"
"log"
"os/exec"
"strings"
)
func upper(data string) string {
return strings.ToUpper(data)
}
func main() {
cmd := exec.Command("echo", "an old falcon")
stdout, err := cmd.StdoutPipe()
if err != nil {
log.Fatal(err)
}
if err := cmd.Start(); err != nil {
log.Fatal(err)
}
data, err := ioutil.ReadAll(stdout)
if err != nil {
log.Fatal(err)
}
if err := cmd.Wait(); err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", upper(string(data)))
}
该示例通过管道读取echo命令的输出并将其转换为大写字母。
cmd := exec.Command("echo", "an old falcon")
要运行的命令是带有单个字符串参数的echo命令。
stdout, err := cmd.StdoutPipe()
我们得到了标准输出管道。
if err := cmd.Start(); err != nil {
log.Fatal(err)
}
命令是用Start函数执行的;它不会等待它完成。
data, err := ioutil.ReadAll(stdout)
我们从管道中读取数据。
if err := cmd.Wait(); err != nil {
log.Fatal(err)
}
Wait等待命令退出并等待任何复制tostdin或从stdout或stderr复制完成。它在看到命令退出后关闭管道。
$ go run stdoutpipe.go AN OLD FALCON
在本教程中,我们在Golang中执行了外部命令。
列出所有Go教程。
