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
}