//go:build !windows // +build !windows package utils import ( "bytes" "context" log "github.com/sirupsen/logrus" "os/exec" "syscall" "time" ) func ScriptCMD(path string, param ...string) (string, error) { // TODO: 执行command, 没有超时的限制吗?需要升级go版本, 升级到1.6也不行哈, 换一种方式context @jay // cmd := exec.Command(path, param...) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute) defer cancel() cmd := exec.CommandContext(ctx, path, param...) var out bytes.Buffer cmd.Stdout = &out // cmd.Timeout = time.Second * 10 err := cmd.Run() result := out.String() log.Infof("cmd content : [%s] cmd error :[%v]", result, err) if err != nil { log.Errorf("path %s param %v error %s", path, param, err) return result, err } //result = out.String() return result, err } func ScriptCMDNO(path string, param ...string) (string, error) { return ScriptCMD(path, param...) //cmd := exec.Command(path, param...) //var out bytes.Buffer //cmd.Stdout = &out //err := cmd.Run() //if err != nil { // log.Error(err) // return "", err //} //result := out.String() //return result, err } // 提权cmd func AuthoritativeCMD(uid32 uint32, waitTime time.Duration, osEnv []string, command string, args ...string) (string, error) { log.Infof("AuthoritativeCMD [command = %s][args = %v][waitTime=%v][uid=%d]", command, args, waitTime, uid32) ctx, cancel := context.WithTimeout(context.Background(), waitTime) defer cancel() cmd := exec.CommandContext(ctx, command, args...) cmd.Env = osEnv cmd.SysProcAttr = &syscall.SysProcAttr{ // 设置子进程为相同pgid,防止子进程再次fork的子进程脱管 //Setpgid: true, // 提权执行 Credential: &syscall.Credential{ Uid: uid32, }, } go func() { defer func() { if err := recover(); err != nil { log.Errorf("AuthoritativeCMD panic:%v", err) } }() select { case <-ctx.Done(): err := syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL) if err == nil { log.Warnf("Timeout kill success : [%d], err:[%v]", cmd.Process.Pid, err) } } }() content, err := cmd.CombinedOutput() log.Infof("cmd content : [%s] cmd error :[%v]", content, err) if err != nil { return string(content), err } return string(content), err } func BackgroundCMD(uid32 uint32, waitTime time.Duration, osEnv []string, command string, args ...string) (string, error) { return "ok", nil }