func (c *Cmds) RunCmd(cmd *exec.Cmd) error {
	log.Info("Running", cmd.Args)
	defer c.remove(cmd)
	err := cmd.Run()
	log.Info("Run Done: ", err)
	return err
}
RunCmd runs a Cmd that was created by Command
package setup
import (
	"fmt"
	"os"
	"os/exec"
	"os/signal"
	"sync"
	"syscall"
	"time"
	log "github.com/sirupsen/logrus"
)
type Cmds struct {
	watching []*exec.Cmd
	mu       sync.Mutex
	wg     sync.WaitGroup
	killed bool
}
func NewCmds() *Cmds {
	return &Cmds{}
}
func NewSignalHandlingCmds() *Cmds {
	r := NewCmds()
	sigchan := make(chan os.Signal, 1)
	signal.Notify(sigchan, syscall.SIGINT, syscall.SIGTERM)
	go func() {
		var sig os.Signal
		sig = <-sigchan
		log.Infof("signal %s received; shutting down", sig)
		r.Kill()
		os.Exit(1)
	}()
	return r
}
func (c *Cmds) Kill() {
	c.mu.Lock()
	defer c.mu.Unlock()
	if c.killed {
		return
	}
	c.killed = true
	log.Infof("Killing %d cmds", len(c.watching))
	allDoneCh := make(chan struct{})
	go func() {
		c.wg.Wait()
		close(allDoneCh)
	}()
	if len(c.watching) == 0 {
		return
	}
	for _, c := range c.watching {
		if p := c.Process; p != nil {
			log.Infof("SIGINT: %d %v", p.Pid, c.Path)
			syscall.Kill(-1*p.Pid, syscall.SIGINT)
		}
	}
	c.mu.Unlock()
	select {
	case <-allDoneCh:
		log.Infof("All completed")
	case <-time.After(5 * time.Second):
		log.Infof("Still waiting; killing all")
	}
	c.mu.Lock()
	if len(c.watching) == 0 {
		return
	}
	for _, c := range c.watching {
		if p := c.Process; p != nil {
			log.Infof("SIGKILL: %d %v", p.Pid, c.Path)
			syscall.Kill(-1*p.Pid, syscall.SIGKILL)
		}
	}
}
func (c *Cmds) Command(path string, arg ...string) *exec.Cmd {
	c.mu.Lock()
	log.Infof("RunCmd: %s %s\n", path, arg)
	defer c.mu.Unlock()
	cmd := exec.Command(path, arg...)
	cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
	cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
	c.wg.Add(1)
	c.watching = append(c.watching, cmd)
	return cmd
}
func (c *Cmds) StartCmd(cmd *exec.Cmd) error {
	c.mu.Lock()
	defer c.mu.Unlock()
	if c.killed {
		return fmt.Errorf("killed; cannot start new cmds")
	}
	log.Info("Starting", cmd.Args)
	err := cmd.Start()
	if err == nil {
		go func() {
			pid := cmd.Process.Pid
			log.Infof("Cmd %v started as %v", cmd.Args, pid)
			cmd.Wait()
			log.Infof("Cmd %v (%v) finished", pid, cmd.Path)
			c.remove(cmd)
			c.Kill()
		}()
	}
	return err
}