os/exec 使用

Administrator
发布于 2023-09-12 / 102 阅读 / 0 评论 / 0 点赞

os/exec 使用

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