-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy path06-exec-cmd.go
65 lines (55 loc) · 1.99 KB
/
06-exec-cmd.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/* This is exercise Q29, in Chapter 7: Communications, from "Learning Go"
by Miek Gieben.
Write a program that takes a list of all running processes and prints
how many child processes each parent has spawned. The output should
look like:
Pid 0 has 2 children: [1 2]
Pid 490 has 2 children: [1199 26524]
Pid 1824 has 1 child: [7293]
This was an example of running external commands via golang. Other
interesting reads are:
http://golang.org/pkg/os/exec
http://golang.org/pkg/os
http://gobyexample.com/execing-processes
http://stackoverflow.com/questions/10027477/golang-fork-process
https://code.google.com/p/go/issues/detail?id=227
https://github.com/golang-samples/exec
http://github.com/dinedal/textql/blob/master/main.go
You can detach your exec command from the go program itself by using
StartProcess and setting stdin, stdout, and stderr to nil. The above
textql github example uses this approach to enter into a standalone
sqlite3 session.
*/
package main
import (
"fmt"
"os/exec"
"sort"
"strconv"
"strings"
)
func main() {
ps := exec.Command("ps", "-e", "-opid,ppid,comm")
output, _ := ps.Output()
child := make(map[int][]int)
for i, s := range strings.Split(string(output), "\n") {
if i == 0 { continue } // skip header
if len(s) == 0 { continue } // skip last line, itself
f := strings.Fields(s)
fpp, _ := strconv.Atoi(f[1]) // parent's pid
fp, _ := strconv.Atoi(f[0]) // child's pid
child[fpp] = append(child[fpp], fp)
}
schild := make([]int, len(child))
i := 0
for k, _ := range child { schild[i] = k; i++ }
sort.Ints(schild)
for _, ppid := range schild {
fmt.Printf("Pid %d has %d child", ppid, len(child[ppid]))
if len(child[ppid]) == 1 {
fmt.Printf(": %v\n", child[ppid])
continue
}
fmt.Printf("ren: %v\n", child[ppid])
}
}