mirror of https://github.com/ouqiang/gocron
修复在Unix-like系统上, exec.command启动的子孙进程, 调用cmd.Process.Kill()不能结束
parent
4c07b02706
commit
14295049d2
|
@ -86,10 +86,11 @@ func Exec(sshConfig SSHConfig, cmd string) (output string, err error) {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
|
|
||||||
// 后台运行
|
// 后台运行
|
||||||
if sshConfig.ExecTimeout < 0 {
|
if sshConfig.ExecTimeout < 0 {
|
||||||
go session.CombinedOutput(cmd)
|
go session.CombinedOutput(cmd)
|
||||||
time.Sleep(3 * time.Second)
|
time.Sleep(10 * time.Second)
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
// 不限制超时
|
// 不限制超时
|
||||||
|
|
|
@ -10,22 +10,33 @@ import (
|
||||||
"github.com/Tang-RoseChild/mahonia"
|
"github.com/Tang-RoseChild/mahonia"
|
||||||
"strings"
|
"strings"
|
||||||
"os"
|
"os"
|
||||||
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
// 执行shell命令,可设置执行超时时间
|
// 执行shell命令,可设置执行超时时间
|
||||||
|
// todo Windows不能KILL掉子进程, 需特殊处理
|
||||||
func ExecShellWithTimeout(timeout int, command string, args... string) (string, error) {
|
func ExecShellWithTimeout(timeout int, command string, args... string) (string, error) {
|
||||||
cmd := exec.Command(command, args...)
|
cmd := exec.Command(command, args...)
|
||||||
|
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||||
|
Setpgid: true,
|
||||||
|
}
|
||||||
|
|
||||||
// 不限制超时时间
|
// 后台运行
|
||||||
if timeout <= 0 {
|
if timeout == -1 {
|
||||||
|
go cmd.CombinedOutput()
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
// 不限制超时
|
||||||
|
if timeout == 0 {
|
||||||
output ,err := cmd.CombinedOutput()
|
output ,err := cmd.CombinedOutput()
|
||||||
return string(output), err
|
return string(output), err
|
||||||
}
|
}
|
||||||
|
|
||||||
d := time.Duration(timeout) * time.Second
|
d := time.Duration(timeout) * time.Second
|
||||||
timer := time.AfterFunc(d, func() {
|
timer := time.AfterFunc(d, func() {
|
||||||
// 超时kill进程
|
// 超时kill进程
|
||||||
cmd.Process.Kill()
|
syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
|
||||||
})
|
})
|
||||||
output ,err := cmd.CombinedOutput()
|
output ,err := cmd.CombinedOutput()
|
||||||
timer.Stop()
|
timer.Stop()
|
||||||
|
@ -33,6 +44,8 @@ func ExecShellWithTimeout(timeout int, command string, args... string) (string,
|
||||||
return string(output), err
|
return string(output), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 生成长度为length的随机字符串
|
// 生成长度为length的随机字符串
|
||||||
func RandString(length int64) string {
|
func RandString(length int64) string {
|
||||||
sources := []byte("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
sources := []byte("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||||
|
|
|
@ -138,6 +138,9 @@ func Store(ctx *macaron.Context, form TaskForm) string {
|
||||||
if taskModel.NotifyStatus > 0 && taskModel.NotifyReceiverId == "" {
|
if taskModel.NotifyStatus > 0 && taskModel.NotifyReceiverId == "" {
|
||||||
return json.CommonFailure("请至少选择一个接收者", err)
|
return json.CommonFailure("请至少选择一个接收者", err)
|
||||||
}
|
}
|
||||||
|
if taskModel.Protocol == models.TaskHTTP && taskModel.Timeout == -1 {
|
||||||
|
return json.CommonFailure("HTTP任务不支持后台运行", err)
|
||||||
|
}
|
||||||
if id == 0 {
|
if id == 0 {
|
||||||
id, err = taskModel.Create()
|
id, err = taskModel.Create()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -233,7 +233,7 @@ func createTaskLog(taskModel models.TaskHost, status models.Status) (int64, stri
|
||||||
taskLogModel.Status = status
|
taskLogModel.Status = status
|
||||||
// SSH执行远程命令,后台运行
|
// SSH执行远程命令,后台运行
|
||||||
var notifyId string = ""
|
var notifyId string = ""
|
||||||
if taskModel.Timeout == -1 && taskModel.Protocol == models.TaskSSH {
|
if taskModel.Timeout == -1 {
|
||||||
notifyId = utils.RandString(32);
|
notifyId = utils.RandString(32);
|
||||||
taskLogModel.NotifyId = notifyId;
|
taskLogModel.NotifyId = notifyId;
|
||||||
}
|
}
|
||||||
|
@ -320,7 +320,7 @@ func afterExecJob(taskModel models.TaskHost, taskResult TaskResult, taskLogId in
|
||||||
if taskResult.Err != nil {
|
if taskResult.Err != nil {
|
||||||
taskResult.Result = taskResult.Err.Error() + "\n" + taskResult.Result
|
taskResult.Result = taskResult.Err.Error() + "\n" + taskResult.Result
|
||||||
}
|
}
|
||||||
if taskModel.Protocol == models.TaskSSH && taskModel.Timeout == -1 {
|
if taskModel.Timeout == -1 {
|
||||||
taskResult.IsAsync = true
|
taskResult.IsAsync = true
|
||||||
}
|
}
|
||||||
_, err := updateTaskLog(taskLogId, taskResult)
|
_, err := updateTaskLog(taskLogId, taskResult)
|
||||||
|
|
Loading…
Reference in New Issue