golang调用shell命令标准输出阻塞管道

Posted 陌上花开

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang调用shell命令标准输出阻塞管道相关的知识,希望对你有一定的参考价值。

 

 

package tools

import (
 "bufio"
 "errors"
 "fmt"
 "github.com/Sirupsen/logrus"
 "go.pkg.okcoin.com/devops/agent/internal/constant"
 "os/exec"
 "strings"
)

/**
return cmdlog,error
*/
func ExecShell(shellPath ...string) (string, error) {
 cmd := exec.Command("/bin/sh", shellPath...)
 stdout, err := cmd.StdoutPipe()
 if err != nil {
  logrus.Errorf("StdoutPipe:%s ", err.Error())
  return fmt.Sprintf("StdoutPipe:%s ", err.Error()), err
 }

 stderr, err := cmd.StderrPipe()
 if err != nil {
  logrus.Errorf("StderrPipe:%s ", err.Error())
  return fmt.Sprintf("StderrPipe:%s ", err.Error()), err
 }

 if err := cmd.Start(); err != nil {
  logrus.Errorf("Start:%s ", err.Error())
  return fmt.Sprintf("Start:%s ", err.Error()), err
 }

 //读取标准输出
 strStdout,_ := rsyncStd(bufio.NewReader(stdout))
 //读取标准错误输出
 strStderr,_ := rsyncStd(bufio.NewReader(stderr))

 //不包含tail -f(这个是配合业务日志输出) GROUP_ID(以root用户执行admin用户的操作) NEW_PASSWD(创建用户)
 if strStderr != "" &&
  !strings.Contains(strStderr, constant.SHELL_EXEC_LOG_TAILF) &&
  !strings.Contains(strStderr, constant.SHELL_EXEC_LOG_GROUP_ID) &&
  !strings.Contains(strStderr, constant.SHELL_EXEC_LOG_NEW_PWD) {
  logrus.Errorf("exec shell fail!err:%s ,execLog:%s", strStderr, strStdout)
  return strStderr, errors.New(fmt.Sprintf("exec fail!err:%s,execLog:%s", strStderr, strStdout))
 }
 if strStderr != "" {
  logrus.Errorf("exec shell fail!err:%s ,execLog:%s", strStderr, strStdout)
 }

 if err := cmd.Wait(); err != nil {
  logrus.Errorf("Wait:%s ,execLog:%s", err.Error(), strStdout)
  return fmt.Sprintf("Wait:%s,execLog:%s ", err.Error(), strStdout), err
 }

 return strStdout, nil
}

func rsyncStd(stdBuf *bufio.Reader)(string ,error){
 var lines []string
 for {
  b, _, err := stdBuf.ReadLine()
  if err != nil {
   if err.Error() != "EOF" {
    return "", err
   }
   break
  }
  lines = append(lines, string(b))
 }
 return strings.Join(lines,"\n"),nil
}

 

以上是关于golang调用shell命令标准输出阻塞管道的主要内容,如果未能解决你的问题,请参考以下文章

php执行shell不阻塞方法

Linux shell编程:管道和重定向

子命令实时Golang管道输出

linux下如何用c语言调用shell命令

golang 将套接字附加到标准输入/标准输出

linux shell 基础-2