process.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package process
  2. import (
  3. "bytes"
  4. "context"
  5. "os/exec"
  6. )
  7. type Process struct {
  8. cmd *exec.Cmd
  9. cancel context.CancelFunc
  10. errorOutput *bytes.Buffer
  11. stdOutput *bytes.Buffer
  12. beforeStopHandler func()
  13. stopped bool
  14. }
  15. func New(path string, params []string) *Process {
  16. return NewWithEnvs(path, params, nil)
  17. }
  18. func NewWithEnvs(path string, params []string, envs []string) *Process {
  19. ctx, cancel := context.WithCancel(context.Background())
  20. cmd := exec.CommandContext(ctx, path, params...)
  21. cmd.Env = envs
  22. p := &Process{
  23. cmd: cmd,
  24. cancel: cancel,
  25. }
  26. p.errorOutput = bytes.NewBufferString("")
  27. p.stdOutput = bytes.NewBufferString("")
  28. cmd.Stderr = p.errorOutput
  29. cmd.Stdout = p.stdOutput
  30. return p
  31. }
  32. func (p *Process) Start() error {
  33. return p.cmd.Start()
  34. }
  35. func (p *Process) Stop() error {
  36. if p.stopped {
  37. return nil
  38. }
  39. defer func() {
  40. p.stopped = true
  41. }()
  42. if p.beforeStopHandler != nil {
  43. p.beforeStopHandler()
  44. }
  45. p.cancel()
  46. return p.cmd.Wait()
  47. }
  48. func (p *Process) ErrorOutput() string {
  49. return p.errorOutput.String()
  50. }
  51. func (p *Process) StdOutput() string {
  52. return p.stdOutput.String()
  53. }
  54. func (p *Process) SetBeforeStopHandler(fn func()) {
  55. p.beforeStopHandler = fn
  56. }