golang爬坑:操作Linux命令

  通常在启动项目服务程序的时候,需要判断该服务是否已经被启动,一般的做法有两种,其一是每次启动后将pid写入文件中,启动的时候读取这个文件,如果里面有数值,就表示服务已启动;另一种是通过shell命令查找:

ps -ef | grep XXX | grep -v grep | awk '{print $2}'

很多语言都可以直接执行这行命令;偏偏go语言不行,因此,我们可以利用go中提供的一些方法实现它(不说了,直接上代码):

func Pipeline(cmds ...*exec.Cmd) (pipeLineOutput, collectedStandardError []byte, pipeLineError error) {
   if len(cmds) < 1 {
       return nil, nil, nil
  }

   var output bytes.Buffer
   var stderr bytes.Buffer

   last := len(cmds) - 1
   for i, cmd := range cmds[:last] {
       var err error
       if cmds[i+1].Stdin, err = cmd.StdoutPipe(); err != nil {
           return nil, nil, err
      }
       cmd.Stderr = &stderr
  }

   cmds[last].Stdout, cmds[last].Stderr = &output, &stderr

   for _, cmd := range cmds {
       if err := cmd.Start(); err != nil {
           return output.Bytes(), stderr.Bytes(), err
      }
  }

   for _, cmd := range cmds {
       if err := cmd.Wait(); err != nil {
           return output.Bytes(), stderr.Bytes(), err
      }
  }

   return output.Bytes(), stderr.Bytes(), nil
}

func ExecPipeLine(cmds ...*exec.Cmd) (string, error) {
   output, stderr, err := Pipeline(cmds...)
   if err != nil {
       return "", err
  }

   if len(output) > 0 {
       return string(output), nil
  }

   if len(stderr) > 0 {
       return string(stderr), nil
  }
   return "", errors.New("no returns")
}

 接着写一个例子测试:

func main() {
   cmds := []*exec.Cmd{
       exec.Command("ps", "-ef"),
       exec.Command("grep", "redis"),
       exec.Command("grep", "-v", "grep"),
       exec.Command("awk", "{print $2}"),
  }
   string, _ := pipeutil.ExecPipeLine()
   fmt.Printf("pids: %v", string)
}

  Bingo!切记,最后一行 awk的参数不能有单引号(‘’)(当时被坑惨了。。。)

posted on 2022-08-10 14:18  root-123  阅读(203)  评论(0编辑  收藏  举报