golang杀死进程组

当我们想杀死一个进程及其所创建的所有子进程,我们可以使用 linux 命令 kill -- -pid

执行 tail -f  ./text.log| grep -a "5t6hwhu1" >../a330fec0-f946-5e47-1be3-5c42ef040c78.tmp

⇒  ps -lf
  UID   PID  PPID        F CPU PRI NI       SZ    RSS WCHAN     S             ADDR TTY           TIME CMD              STIME
  501   407   323     4006   0  31  0  4337800  14192 -      Ss                  0 ttys000    0:00.03 /Applications/iT  8:45上午
  501   411   409     4006   0  31  0  4334036   2472 -      S+                  0 ttys000    0:00.85 -zsh              8:45上午
  501  1421  1418     4006   0  31  0  4334036   1412 -      Ss+                 0 ttys001    0:00.31 zsh -l            9:28上午
  501   635   630     4006   0  31  0  4334036   1396 -      Ss+                 0 ttys002    0:00.38 zsh -l            8:45上午
  501  1517   323     4006   0  31  0  4347016  14192 -      Ss                  0 ttys003    0:00.04 /Applications/iT  9:33上午
  501  1519  1518     4006   0  31  0  4337016   4088 -      S                   0 ttys003    0:01.25 -zsh              9:33上午
  501  3919  1418     4006   0  31  0  4334036   3972 -      Ss                  0 ttys004    0:00.56 zsh -l           11:48上午
  501  6550  3919     4006   0  31  0  4277244    700 -      S+                  0 ttys004    0:00.00 tail -f ./text.l 12:33下午
  501  6551  3919     4006   0  31  0  4268036    812 -      S+                  0 ttys004    0:00.00 grep --color=aut 12:33下午

会发现生成了两个进程,一个是tail(pid:6550),另一个是grep(pid:6551),我们想杀死这两个进程,  kill -- -6550

 

golang中我们想执行 tail -f  ./text.log| grep -a "5t6hwhu1" >../a330fec0-f946-5e47-1be3-5c42ef040c78.tmp,发现会生成三个进程

⇒  ps -lf
  UID   PID  PPID        F CPU PRI NI       SZ    RSS WCHAN     S             ADDR TTY           TIME CMD              STIME
  501   407   323     4006   0  31  0  4337800  14192 -      Ss                  0 ttys000    0:00.03 /Applications/iT  8:45上午
  501   411   409     4006   0  31  0  4334036   1440 -      S+                  0 ttys000    0:00.85 -zsh              8:45上午
  501  1421  1418     4006   0  31  0  4334036   1412 -      Ss+                 0 ttys001    0:00.31 zsh -l            9:28上午
  501   635   630     4006   0  31  0  4334036   1396 -      Ss+                 0 ttys002    0:00.38 zsh -l            8:45上午
  501  1517   323     4006   0  31  0  4347016  14192 -      Ss                  0 ttys003    0:00.04 /Applications/iT  9:33上午
  501  1519  1518     4006   0  31  0  4337016   4012 -      S                   0 ttys003    0:01.34 -zsh              9:33上午
  501  3919  1418     4006   0  31  0  4334036   3944 -      Ss                  0 ttys004    0:00.61 zsh -l           11:48上午
  501  6715  3919     4006   0  31  0  4371416   2344 -      S+                  0 ttys004    0:00.01 ./test           12:40下午
  501  6716  6715     4006   0  31  0  4268616   1100 -      S                   0 ttys004    0:00.00 bash -c  tail -f 12:40下午
  501  6717  6716     4006   0  31  0  4268028    684 -      S                   0 ttys004    0:00.00 tail -f ./text.l 12:40下午
  501  6718  6716     4006   0  31  0  4277252    824 -      S                   0 ttys004    0:00.00 grep -a 5t6hwhu1 12:40下午

./test 进程生成了6716进程,6716生成了6717和6718进程,可以使用golang中syscall.Kill()

  1 package main
  2 
  3 import (
  4     "bytes"
  5     "fmt"
  6     "log"
  7     "os"
  8     "os/exec"
  9     "strconv"
 10     "syscall"
 11     "time"
 12 )
 13 
 14 func main() {
 15     go Write()
 16     go Process()
 17 
 18     fmt.Println("goroutine is ok.")
 19     time.Sleep(time.Second * 100)
 20 }
 21 
 22 // 非阻塞模式执行bash
 23 func Process() {
 24     // "bash", "-c", "./1.sh"
 25     // 会启动两个进程 tail 和 一个 grep 进程,kill只会杀掉 3190 进程
 26     // 501  3987  3986     4006   0  31  0  4268616   1100 -      S                   0 ttys004    0:00.00 bash -c  tail -f 11:48上午
 27     // 501  3988  3987     4006   0  31  0  4268028    684 -      S                   0 ttys004    0:00.00 tail -f ./text.l 11:48上午
 28     // 501  3989  3987     4006   0  31  0  4270084    832 -      S                   0 ttys004    0:00.00 grep -a 5t6hwhu1 11:48上午
 29 
 30     s := ` tail -f  ./text.log| grep -a "5t6hwhu1" >../a330fec0-f946-5e47-1be3-5c42ef040c78.tmp`
 31     cmd := exec.Command("bash", "-c", s)
 32 
 33     // Go会将PGID设置成与PID相同的值
 34     cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
 35 
 36     r, err := cmd.StdoutPipe()
 37     if err != nil {
 38         fmt.Println("stdout pipe is failed, err:", err)
 39     }
 40 
 41     err = cmd.Start()
 42     if err != nil {
 43         log.Fatal(err)
 44     }
 45 
 46     go KillProcess(cmd)
 47 
 48     p := make([]byte, 1024*4)
 49     for {
 50         time.Sleep(time.Second * 1)
 51         n, err := r.Read(p)
 52         if err != nil {
 53             fmt.Println("read is failed, err:", err)
 54             break
 55         }
 56 
 57         // 如果分隔符的为最后一位,则会分割出来两个数组,第二个数组长度为0
 58         lines := bytes.Split(p[0:n], []byte("\n"))
 59         for _, line := range lines {
 60             if len(line) <= 0 {
 61                 continue
 62             }
 63 
 64             // 新的一行内容
 65         }
 66 
 67         fmt.Println("---n=", n, cmd.Process.Pid, "read=", string(p[0:n]), "len(line)=", len(lines))
 68     }
 69 
 70     // 可用 wait 等待 shell 执行结果
 71     err = cmd.Wait()
 72 }
 73 
 74 func KillProcess(cmd *exec.Cmd) {
 75     fmt.Println("sleep ~~~~")
 76     time.Sleep(time.Second * 15)
 77 
 78     err := syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
 79     if err != nil {
 80         fmt.Println("kill process team is failed, err:", err)
 81     }
 82     fmt.Println("kill process team is ok")
 83 
 84     // time.Sleep(time.Second * 10)
 85     // 如果执行下面只会杀死 3987 进程, 3988、3989 还会存活
 86     // err := cmd.Process.Kill()
 87     // if err != nil {
 88     //     fmt.Println("kill is failed, err:", err)
 89     // }
 90 
 91     fmt.Println("kill tail. ")
 92 }
 93 
 94 func Write() {
 95     f, err := os.OpenFile("./text.log", os.O_TRUNC|os.O_CREATE|os.O_RDWR, 0644)
 96     if err != nil {
 97         fmt.Println("open file is failed,err:", err)
 98     }
 99 
100     for i := 0; i <= 100; i++ {
101         time.Sleep(time.Second * 2)
102         f.WriteString("write log " + strconv.Itoa(i) + "----------------------------------------cc\n")
103     }
104 }

 

上一篇:Android厂商推送冲突了。。,kotlin语法


下一篇:docker常用命令的使用