📚 开源资源分享——颜佐光的个人书架
✉️ 联系站长
书架 / go / 系统

go语言exec包的使用

2020-06-20 20:18 · 约 2,127 字 · 浏览 2,811 次系统

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)
← 返回《go》目录书架 →