/
oexec.go
71 lines (63 loc) · 1.77 KB
/
oexec.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
66
67
68
69
70
71
package oexec
import (
"os/exec"
"strings"
"sync"
)
// Series will execute specified cmds in series and return slice of Outputs
func Series(cmds ...string) []*Output {
outputs := make([]*Output, len(cmds))
for index, cmd := range cmds {
outputs[index] = run(cmd)
}
return outputs
}
// Parallel will execute specified cmds in parallel and return slice of
// Outputs when all of them have completed
func Parallel(cmds ...string) []*Output {
var wg sync.WaitGroup
outputs := make([]*Output, len(cmds))
for index, cmd := range cmds {
wg.Add(1)
go runParallel(&wg, cmd, index, outputs)
}
wg.Wait()
return outputs
}
// runParallel is a helper go routine to run cmd in async
// and put result into array
func runParallel(wg *sync.WaitGroup, cmd string, index int, outputs []*Output) {
defer wg.Done()
outputs[index] = run(cmd)
}
// run will process the specified cmd, execute it and return the Output struct
func run(cmd string) *Output {
cmdName, cmdArgs := processCmdStr(cmd)
outStruct := new(Output)
outStruct.Stdout, outStruct.Stderr = execute(cmdName, cmdArgs...)
return outStruct
}
// removeEmptyStr will remove empty strings from the slice
func removeEmptyStr(s []string) []string {
var r []string
for _, str := range s {
if str != "" && str != " " {
r = append(r, str)
}
}
return r
}
// processCmdStr will split full command string to command and arguments slice
func processCmdStr(cmd string) (cmdName string, cmdArgs []string) {
cmdParts := removeEmptyStr(strings.Split(cmd, " "))
return cmdParts[0], cmdParts[1:]
}
// execute will run the specified command with arguments
// and return output, error
func execute(cmd string, args ...string) ([]byte, error) {
out, err := exec.Command(cmd, args...).Output()
if err != nil {
return nil, err
}
return out, nil
}