在 Go 中调用系统命令
os/exec 包用来执行外部命令或者与外部命令交互
启动一个程序
package main
import (
"bytes"
"fmt"
"log"
"os/exec"
)
func main() {
cmd := exec.Command("ls")
if err := cmd.Run(); err != nil {
log.Fatalf("failed to call cmd.Run(): %v", err)
}
}
此处执行的 Run 命令,执行结束程序就结束了,没有输出执行结果,需要添加标准输出使结果打印出来
package main
import (
"bytes"
"fmt"
"log"
"os/exec"
)
func main() {
cmd := exec.Command("ls")
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
log.Fatalf("failed to call cmd.Run(): %v", err)
}
fmt.Println(stdout.String())
fmt.Println(stderr.String())
}
管道使用 Pipe
package main
import (
"bytes"
"fmt"
"log"
"os/exec"
"strings"
)
func main() {
cmd := exec.Command("tr", "a-z", "A-Z")
cmd.Stdin = strings.NewReader("some input")
var stdout bytes.Buffer
cmd.Stdout = &stdout
if err := cmd.Run(); err != nil {
log.Fatalf("failed to call cmd.Run(): %v", err)
}
fmt.Println(stdout.String())
}
此处用了一个标准输入, 输入给stdin
一个some input
字符串,结果输出的是大写SOME INPUT
,相当于执行的 linux 命令 echo "some input" | tr "a-z" "A-Z"
package main
import (
"bytes"
"fmt"
"log"
"os/exec"
)
func main() {
lscmd := exec.Command("ls")
wccmd := exec.Command("wc", "-l")
wccmd.Stdin, _ = lscmd.StdoutPipe()
var stdout bytes.Buffer
wccmd.Stdout = &stdout
if err := lscmd.Start(); err != nil {
log.Fatalf("failed to call lscmd.Run(): %v", err)
}
if err := wccmd.Start(); err != nil {
log.Fatalf("failed to call wccmd.Run(): %v", err)
}
lscmd.Wait()
wccmd.Wait()
fmt.Println(stdout.String())
}
此处使用了一个两个 Command,把第一个的标准输出输入给第二个的标准输入。
bash 使用
package main
import (
"bytes"
"fmt"
"log"
"os/exec"
)
func main() {
cmd := exec.Command("bash", "-c", "ls | wc -l")
var stdout bytes.Buffer
cmd.Stdout = &stdout
if err := cmd.Run(); err != nil {
log.Fatalf("failed to call lscmd.Run(): %v", err)
}
fmt.Println(stdout.String())
}
bash 支持在 command 中使用管道,默认是不能使用的,这就使得 bash 能够编写简单