Kill进程及其子进程,以及处在sleep或者阻塞状态中的程序,如果使用cmd.Process.Kill()是没发达到这些效果。
cmd := exec.Command("/bin/sh", "-c", "...........")
// Go会将PGID设置成与PID相同的值
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
eg
package main
import (
"fmt"
"os"
"os/exec"
"syscall"
"time"
)
func main() {
args := []string{
"/bin/bash",
"/Users/joy/src/testGo/test.sh",
"world",
}
env := []string{
"TEST=1",
"ERROR=NONE",
}
cmd := exec.Cmd{
Path: "/bin/bash", // 可执行程序
Args: args, // 参数
Env: env, // 环境变量k=v
}
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
c := make(chan string, 1)
c <- "test start"
timeout := time.After(5 * time.Second)
for {
select {
case s := <-c:
go func() {
fmt.Println(s)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Start(); err != nil {
fmt.Printf("cmd start err %s\n", err)
return
}
fmt.Printf("start task %s\n", time.Now())
err := cmd.Wait()
if err != nil {
fmt.Printf("cmd wait failed %s\n", err)
}
fmt.Println("cmd exit ", cmd.ProcessState.ExitCode())
fmt.Println("test end.")
os.Exit(0)
}()
case <-timeout:
err := syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
if err == nil {
fmt.Printf("kill cmd[%s] success!\n", cmd.String())
} else {
fmt.Printf("kill error %s\n", err)
}
}
}
}
其中外部程序test.sh
#!/bin/bash
date
echo $1
echo $ERROR
sleep 10
date