diff --git a/cmd/agent/main.go b/cmd/agent/main.go index 76515a9..3d57b65 100644 --- a/cmd/agent/main.go +++ b/cmd/agent/main.go @@ -11,6 +11,7 @@ import ( "os" "os/exec" "strings" + "syscall" "time" "github.com/blang/semver" @@ -232,30 +233,30 @@ func doTask(task *pb.Task) { case model.TaskTypeCommand: startedAt := time.Now() var cmd *exec.Cmd - var resChan chan string - var errChan chan string - timeout := time.NewTimer(time.Minute * 30) + var endCh = make(chan struct{}) + timeout := time.NewTimer(time.Hour * 2) if utils.IsWindows() { cmd = exec.Command("cmd", "/c", task.GetData()) } else { cmd = exec.Command("sh", "-c", task.GetData()) } - go func(resChan, errChan chan string) { - output, err := cmd.Output() - if err != nil { - errChan <- fmt.Sprintf("%s\n%s", string(output), err.Error()) - return + cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} + go func() { + select { + case <-timeout.C: + result.Data = "任务执行超时\n" + cmd.Process.Kill() + close(endCh) + case <-endCh: } - resChan <- string(output) - }(resChan, errChan) - select { - case <-timeout.C: - result.Data = "任务执行超时(30分钟)" - case output := <-resChan: - result.Data = output + }() + output, err := cmd.Output() + if err != nil { + result.Data += fmt.Sprintf("%s\n%s", string(output), err.Error()) + } else { + close(endCh) + result.Data = string(output) result.Successful = true - case errString := <-errChan: - result.Data = errString } result.Delay = float32(time.Now().Sub(startedAt).Seconds()) default: diff --git a/cmd/playground/example.sh b/cmd/playground/example.sh index fac9411..449a159 100755 --- a/cmd/playground/example.sh +++ b/cmd/playground/example.sh @@ -3,8 +3,8 @@ set -x ME=`whoami` -ping example.com -c3 && \ +ping example.com -c20 && \ echo "==== $ME ====" && \ - ping example.net -c3 && \ + ping example.net -c20 && \ echo $1 && \ echo "==== done! ====" \ No newline at end of file diff --git a/cmd/playground/main.go b/cmd/playground/main.go index 73b1429..c1a76b1 100644 --- a/cmd/playground/main.go +++ b/cmd/playground/main.go @@ -8,6 +8,7 @@ import ( "net/http" "os" "os/exec" + "syscall" "time" "github.com/go-ping/ping" @@ -85,7 +86,22 @@ func cmdExec() { cmd = exec.Command("sh", "-c", execFrom+`/cmd/playground/example.sh hello && \ echo world!`) } - output, err := cmd.Output() - log.Println("output:", string(output)) - log.Println("err:", err) + cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} + var endCh = make(chan struct{}) + go func() { + output, err := cmd.Output() + log.Println("output:", string(output)) + log.Println("err:", err) + close(endCh) + }() + go func() { + time.Sleep(time.Second * 2) + fmt.Println("killed") + if err := syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL); err != nil { + panic(err) + } + }() + select { + case <-endCh: + } }