不定参数的使用

不定参数的使用

起初学习的蒙蔽状态

在学习不定参数的时候,我认为传切片就好了,没必要这玩意吧。直到看Go文档的cmd时候,exec.Command(name string, args ...string),所以说,存在即合理。

应用场景

在我们想要获取linux服务器的输出状态,获取cpu使用率,内存剩余时候。就需要这个,那么对于通用接口实现,也就是说实现前面输出,后面解析,只用一个函数就能解决一系列问题。

  1. 首先我们来看一下不通用场景(仅仅为了演示不定参数的传参)

    package main
    
    import (
    	"fmt"
    	"os/exec"
    )
    
    func t() {
    	var (
    		cmd *exec.Cmd
    		output []byte
    		err error
    	)
    
    	a := []string{"docker", "ps", "-a"}
    	a2 := a[1:]
    	// 生成Cmd
    	cmd = exec.Command(a[0], a2...)
    
    	// 执行了命令, 捕获了子进程的输出( pipe )
    	if output, err = cmd.CombinedOutput(); err != nil {
    		fmt.Println(err)
    		return
    	}
    
    	// 打印子进程的输出
    	fmt.Println(string(output))
    }
    
    func main() {
    	t()
    }
    

    代码重点

    a := []string{"docker", "ps", "-a"}
    a2 := a[1:]
    // 生成Cmd
    cmd = exec.Command(a[0], a2...)
    
    1. 实际案例(前端输入字符串,后台解析为linux命令)

      // 执行后台任务 输出到前台
      // 前台的文件是以 "," 为分隔符
      func CmdHandle(c *gin.Context) {
      	var (
      		sliceCmd []string
      		sliceCmdHead string
      		sliceOther []string
      		output []byte
      		err error
      		cmd *exec.Cmd
      		q string
      	)
      	q = c.Query("cmd")
      	sliceCmd = strings.Split(q, ",")
      
      	sliceCmdHead = sliceCmd[0]
      	sliceOther = sliceCmd[1:]
      
      	cmd = exec.Command(sliceCmdHead, sliceOther...)
      
      	// 执行了命令, 捕获了子进程的输出( pipe )
      	if output, err = cmd.CombinedOutput(); err != nil {
      		fmt.Println(err)
      		return
      	}
      
      	str := string(output)
      
      	strSlice := strings.Split(str, "\n")
      
      	c.JSON(200, gin.H{
      		"msg": "cmd_ok",
      		"cmd": strSlice,
      	})
      }
      

附加

对于上面的代码来说 ,结果输出就是一堆字符串,也就是一团糟,无法解析

下面以查看CPU状态案例来实现结果标准输出解析

cmd标准输出

func CpuStatusHandle(ctx *gin.Context) {
	var (
		cmd           *exec.Cmd
		out           bytes.Buffer
		err           error
		process       []*Process
		line          string
		itemsNoFormat []string // 没格式化的
		items         []string
		pid           string
		cpu           float64
		cpuTotal      float64
		processTmp    Process
	)

	cmd = exec.Command("ps", "u")
	cmd.Stdout = &out
	if err = cmd.Run(); err != nil {
		fmt.Println("cmd_err------------------")
		return
	}

	process = make([]*Process, 0)
	for {
		if line, err = out.ReadString('\n'); err != nil {
			break
		}

		// 格式化命令
		itemsNoFormat = strings.Split(line, " ")
		items = make([]string, 0)
		for _, v := range itemsNoFormat {
			if v != "\t" && v != "" {
				items = append(items, v)
			}
		}

		// 提取pid 和 cpu
		pid = items[1]
		if cpu, err = strconv.ParseFloat(items[2], 64); err != nil {
			fmt.Println("系统异常  解析失败哦哦")
			//break
		}

		cpuTotal += cpu

		processTmp = Process{pid: pid}
		process = append(process, &processTmp)
	}

	ctx.JSON(200, gin.H{
		"cputotal": cpuTotal,
		"cpulist":  process,
	})
}
posted @ 2020-12-13 17:49  maob  阅读(193)  评论(0编辑  收藏  举报