-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathevery.go
121 lines (94 loc) · 1.84 KB
/
every.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
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
package main
import "strings"
import "os/exec"
import "flag"
import "time"
import "log"
import "fmt"
import "os"
//
// Usage
//
const usage = `
Usage: every [options] <interval> <command>
Options:
--no-stdout suppress command stdout
--no-stderr suppress command stderr
--quiet implies --no-{stdout,stderr}
--exit exit on error
Examples:
$ every 5s redis-backup /data/dump.rdb
`
//
// Options
//
var flags = flag.NewFlagSet("every", flag.ContinueOnError)
var nostdout = flags.Bool("no-stdout", false, "")
var nostderr = flags.Bool("no-stderr", false, "")
var quiet = flags.Bool("quiet", false, "")
var exit = flags.Bool("exit", false, "")
//
// Print usage and exit
//
func printUsage() {
fmt.Println(usage)
os.Exit(0)
}
//
// Check `err`
//
func check(err error) {
if err != nil {
log.Fatalf("Error: %s", err)
}
}
//
// Main.
//
func main() {
flags.Usage = printUsage
flags.Parse(os.Args[1:])
argv := flags.Args()
// quiet
if *quiet {
*nostdout = true
*nostderr = true
}
// interval
if len(argv) < 1 {
check(fmt.Errorf("<interval> required"))
}
interval, err := time.ParseDuration(argv[0])
check(err)
// command
if len(argv) < 2 {
check(fmt.Errorf("<command> required"))
}
// command name and args
cmd := strings.Join(argv[1:], " ")
// run
log.Printf("every %s running `%s`", interval, cmd)
for {
time.Sleep(interval)
start := time.Now()
log.Printf("exec `%s`", cmd)
proc := exec.Command("/bin/sh", "-c", cmd)
if !*nostdout {
proc.Stdout = os.Stdout
}
if !*nostderr {
proc.Stderr = os.Stderr
}
proc.Start()
err := proc.Wait()
ps := proc.ProcessState
if err != nil {
log.Printf("pid %d failed with %s", ps.Pid(), ps.String())
if *exit {
os.Exit(1)
}
continue
}
log.Printf("pid %d completed in %s", ps.Pid(), time.Since(start))
}
}