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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
package shell
import "fmt"
import "log"
import "strings"
import "time"
import "os"
import "os/exec"
import "bufio"
import "github.com/davecgh/go-spew/spew"
import "github.com/svent/go-nbreader"
var shellStdout *os.File
var shellStderr *os.File
func Script(cmds string) int {
// split on new lines (while we are at it, handle stupid windows text files
lines := strings.Split(strings.Replace(cmds, "\r\n", "\n", -1), "\n")
for _, line := range lines {
line = strings.TrimSpace(line) // this is like 'chomp' in perl
fmt.Println("LINE:", line)
time.Sleep(1)
Run(line)
}
return 0
}
func SetStdout(newout *os.File) {
shellStdout = newout
}
func SetStderr(newerr *os.File) {
shellStderr = newerr
}
func Run(cmdline string) int {
log.Println("START " + cmdline)
cmd := strings.TrimSpace(cmdline) // this is like 'chomp' in perl
cmdArgs := strings.Fields(cmd)
if (len(cmdArgs) == 0) {
log.Println("END ", cmd)
return 0 // nothing to do
}
if (cmdArgs[0] == "cd") {
if (len(cmdArgs) > 1) {
log.Println("os.Chdir()", cmd)
os.Chdir(cmdArgs[1])
}
log.Println("END ", cmd)
return 0 // nothing to do
}
process := exec.Command(cmdArgs[0], cmdArgs[1:len(cmdArgs)]...)
pstdout, _ := process.StdoutPipe()
pstderr, _ := process.StderrPipe()
spew.Dump(pstdout)
process.Start()
if (shellStdout == nil) {
shellStdout = os.Stdout
}
f := bufio.NewWriter(shellStdout)
newreader := bufio.NewReader(pstdout)
nbr := nbreader.NewNBReader(newreader, 1024)
newerrreader := bufio.NewReader(pstderr)
nbrerr := nbreader.NewNBReader(newerrreader, 1024)
for {
time.Sleep(2 * time.Millisecond) // only check the buffer 500 times a second
// log.Println("sleep done")
oneByte := make([]byte, 1024)
count, err := nbr.Read(oneByte)
if (err != nil) {
// log.Println("Read() count = ", count, "err = ", err)
oneByte = make([]byte, 1024)
count, err = nbr.Read(oneByte)
f.Write([]byte(string(oneByte)))
f.Flush()
}
f.Write([]byte(string(oneByte)))
f.Flush()
oneByte = make([]byte, 1024)
count, err = nbrerr.Read(oneByte)
if (err != nil) {
oneByte = make([]byte, 1024)
count, err = nbrerr.Read(oneByte)
f.Write([]byte(string(oneByte)))
f.Flush()
log.Println("Read() count = ", count, "err = ", err)
spew.Dump(process.Process)
spew.Dump(process.ProcessState)
err := process.Wait()
if err != nil {
spew.Dump(err.(*exec.ExitError))
spew.Dump(process.ProcessState)
stuff := err.(*exec.ExitError)
log.Println("ERROR ", stuff)
log.Println("END ", cmdline)
return -1
}
log.Println("END ", cmdline)
return 0
} else {
f.Write([]byte(string(oneByte)))
f.Flush()
}
// spew.Dump(reflect.ValueOf(cmd.Process).Elem())
}
err := process.Wait()
if err != nil {
spew.Dump(err.(*exec.ExitError))
spew.Dump(process.ProcessState)
stuff := err.(*exec.ExitError)
log.Println("ERROR ", stuff)
log.Println("END ", cmdline)
return -1
}
log.Println("END ", cmdline)
return 0
}
func Daemon(cmdline string, timeout time.Duration) int {
for {
Run(cmdline)
time.Sleep(timeout)
}
}
|