execScriptOther.go 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. //go:build !windows
  2. // +build !windows
  3. package utils
  4. import (
  5. "bytes"
  6. "context"
  7. log "github.com/sirupsen/logrus"
  8. "os/exec"
  9. "syscall"
  10. "time"
  11. )
  12. func ScriptCMD(path string, param ...string) (string, error) {
  13. // TODO: 执行command, 没有超时的限制吗?需要升级go版本, 升级到1.6也不行哈, 换一种方式context @jay
  14. // cmd := exec.Command(path, param...)
  15. ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
  16. defer cancel()
  17. cmd := exec.CommandContext(ctx, path, param...)
  18. var out bytes.Buffer
  19. cmd.Stdout = &out
  20. // cmd.Timeout = time.Second * 10
  21. err := cmd.Run()
  22. result := out.String()
  23. log.Infof("cmd content : [%s] cmd error :[%v]", result, err)
  24. if err != nil {
  25. log.Errorf("path %s param %v error %s", path, param, err)
  26. return result, err
  27. }
  28. //result = out.String()
  29. return result, err
  30. }
  31. func ScriptCMDNO(path string, param ...string) (string, error) {
  32. return ScriptCMD(path, param...)
  33. //cmd := exec.Command(path, param...)
  34. //var out bytes.Buffer
  35. //cmd.Stdout = &out
  36. //err := cmd.Run()
  37. //if err != nil {
  38. // log.Error(err)
  39. // return "", err
  40. //}
  41. //result := out.String()
  42. //return result, err
  43. }
  44. // 提权cmd
  45. func AuthoritativeCMD(uid32 uint32, waitTime time.Duration, osEnv []string, command string, args ...string) (string, error) {
  46. log.Infof("AuthoritativeCMD [command = %s][args = %v][waitTime=%v][uid=%d]", command, args, waitTime, uid32)
  47. ctx, cancel := context.WithTimeout(context.Background(), waitTime)
  48. defer cancel()
  49. cmd := exec.CommandContext(ctx, command, args...)
  50. cmd.Env = osEnv
  51. cmd.SysProcAttr = &syscall.SysProcAttr{
  52. // 设置子进程为相同pgid,防止子进程再次fork的子进程脱管
  53. //Setpgid: true,
  54. // 提权执行
  55. Credential: &syscall.Credential{
  56. Uid: uid32,
  57. },
  58. }
  59. go func() {
  60. defer func() {
  61. if err := recover(); err != nil {
  62. log.Errorf("AuthoritativeCMD panic:%v", err)
  63. }
  64. }()
  65. select {
  66. case <-ctx.Done():
  67. err := syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
  68. if err == nil {
  69. log.Warnf("Timeout kill success : [%d], err:[%v]", cmd.Process.Pid, err)
  70. }
  71. }
  72. }()
  73. content, err := cmd.CombinedOutput()
  74. log.Infof("cmd content : [%s] cmd error :[%v]", content, err)
  75. if err != nil {
  76. return string(content), err
  77. }
  78. return string(content), err
  79. }
  80. func BackgroundCMD(uid32 uint32, waitTime time.Duration, osEnv []string, command string, args ...string) (string, error) {
  81. return "ok", nil
  82. }