在 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 能够编写简单