go语言exec包的使用

/ go / 没有评论 / 2089浏览

go语言exec包的使用

有时候我们的go程序需要执行外部的命令,比如执行linux shell命令,一个其他语言(比如C语言)编写的二进制文件,我们都可以通过调用go语言exec包的函数来执行。下面将介绍exec包的一些简单使用例子。

1. exec.Command执行命令

假设我们要执行调用linux的ping命令,求的5次ping的平均值,可以采用如下方式:

package main

import (
	"bufio"
	"fmt"
	"io"
	"os/exec"
	"strings"
)

func exec_shell(s_cmd string) (string, bool) {
	cmd := exec.Command("/bin/bash", "-c", s_cmd)
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		log.Error("cmd StdoutPipe error:", err)
		return "", false
	}
	cmd.Start()

	var end_line string
	reader := bufio.NewReader(stdout)
	for {
		line, err2 := reader.ReadString('\n')
		if err2 != nil || io.EOF == err2 {
			break
		}
		end_line = line
	}
	 
	fmt.Println(cmd.Process.Pid)
	return end_line, true
}

func ping() string {
	s_cmd := "ping -c 10 127.0.0.1"

	var pline string
	var b bool
	if pline, b = exec_shell(s_cmd); b == false {
		return ""
	}
	arr := strings.Split(pline, " ")
	var a []string
	if len(arr)-2 >= 0 {
		a = strings.Split(arr[len(arr)-2], "/")
	}
	if len(a) >= 2 {
		return a[1]
	}
	return ""
}

func main() {
	for i := 0; i < 10; i++ {
		str := ping()
		fmt.Println(str)
	}
}

其中,各个exec函数的简要介绍如下

func Command(name string, arg ...string) *Cmd
//方法返回一个*Cmd, 用于执行name指定的程序(携带arg参数)

func (c *Cmd) Run() error
//执行Cmd中包含的命令,阻塞直到命令执行完成

func (c *Cmd) Start() error
//执行Cmd中包含的命令,该方法立即返回,并不等待命令执行完成

func (c *Cmd) Wait() error
//该方法会阻塞直到Cmd中的命令执行完成,但该命令必须是被Start方法开始执行的

func (c *Cmd) Output() ([]byte, error)
//执行Cmd中包含的命令,并返回标准输出的切片

func (c *Cmd) CombinedOutput() ([]byte, error)
//执行Cmd中包含的命令,并返回标准输出与标准错误合并后的切片

func (c *Cmd) StdinPipe() (io.WriteCloser, error)
//返回一个管道,该管道会在Cmd中的命令被启动后连接到其标准输入

func (c *Cmd) StdoutPipe() (io.ReadCloser, error)
//返回一个管道,该管道会在Cmd中的命令被启动后连接到其标准输出

func (c *Cmd) StderrPipe() (io.ReadCloser, error)
//返回一个管道,该管道会在Cmd中的命令被启动后连接到其标准错误

2. go检测目标进程是否存在

if err = syscall.Kill(pid,0);err == nil {
    fmt.Println("进程存在")
    return 
}

3. 杀死进程的方式

cmd := exec.Command("/bin/sh", "-c", "...........")
// Go会将PGID设置成与PID相同的值
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
syscall.Kill(cmd.Process.Pid, syscall.SIGKILL)