| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- //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
- }
|