package executor import ( "agent-go/config" "agent-go/g" "bufio" "bytes" "fmt" "os/exec" "time" ) var log = g.G.LOG func Execute(om *config.OctopusMessage, em *config.ExecutionMessage) ([]string, error) { var resultLog []string var err error if em.PipeLineCommand != nil && len(em.PipeLineCommand) != 0 { // 管道命令 resultLog, err = PipeLineCommandExecutor(em.PipeLineCommand) } else if em.MultiLineCommand != nil && len(em.MultiLineCommand) != 0 { // 多行命令 resultLog, err = MultiLineCommandExecutor(em.MultiLineCommand) } else { // 单行命令 resultLog, err = SingleLineCommandExecutor(em.SingleLineCommand) } // 归一化错误和日志 if err != nil { resultLog = append(resultLog, fmt.Sprintf("Error: %s", err.Error())) } // 处理执行日志 // 是否需要返回处理日志,现在默认返回 if em.NeedResultReplay { // 需要返回处理结果 om.ACTime = time.Now() om.Result = resultLog } log.Info(fmt.Sprintf("Executor Result: %s", resultLog)) return resultLog, err } func PipeLineCommandExecutor(pipeLineCommand [][]string) ([]string, error) { var cmds []*exec.Cmd // 创建每个命令对象,并将前一个命令的标准输出连接到当前命令的标准输入 for i, partOfCommand := range pipeLineCommand { cmd := exec.Command(partOfCommand[0], partOfCommand[1:]...) if i > 0 { prevCmd := cmds[i-1] out, err := prevCmd.StdoutPipe() if err != nil { return nil, err } cmd.Stdin = out } cmds = append(cmds, cmd) } // 执行最后一个命令,并获取其输出 lastCmd := cmds[len(cmds)-1] var out bytes.Buffer lastCmd.Stdout = &out lastCmd.Stderr = &out err := lastCmd.Run() scanner := bufio.NewScanner(&out) var result []string for scanner.Scan() { result = append(result, scanner.Text()) } if err != nil { return nil, err } return result, nil } func MultiLineCommandExecutor(multiLineCommandExecutor [][]string) ([]string, error) { var res []string for _, singleLineCommand := range multiLineCommandExecutor { singleLogs, err := SingleLineCommandExecutor(singleLineCommand) res := append(res, singleLogs...) if err != nil { return res, err } } return res, nil } // SingleLineCommandExecutor 执行单行命令 func SingleLineCommandExecutor(singleLineCommand []string) ([]string, error) { cmd := exec.Command(singleLineCommand[0], singleLineCommand[1:]...) var out bytes.Buffer cmd.Stdout = &out cmd.Stderr = &out err := cmd.Run() scanner := bufio.NewScanner(&out) var result []string for scanner.Scan() { result = append(result, scanner.Text()) } if err != nil { return nil, err } return result, nil }