use go-cmd/cmd and purge old code
This commit is contained in:
parent
ae5cadf545
commit
d887da32f2
98
chomp.go
98
chomp.go
|
@ -1,98 +0,0 @@
|
||||||
package shell
|
|
||||||
|
|
||||||
/*
|
|
||||||
perl 'chomp'
|
|
||||||
|
|
||||||
send it anything, always get back a string
|
|
||||||
*/
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"go.wit.com/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// import "github.com/davecgh/go-spew/spew"
|
|
||||||
|
|
||||||
func chompBytesBuffer(buf *bytes.Buffer) string {
|
|
||||||
var bytesSplice []byte
|
|
||||||
bytesSplice = buf.Bytes()
|
|
||||||
|
|
||||||
return Chomp(string(bytesSplice))
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: obviously this is stupidly wrong
|
|
||||||
// TODO: fix this to trim fucking everything
|
|
||||||
// really world? 8 fucking years of this language
|
|
||||||
// and I'm fucking writing this? jesus. how the
|
|
||||||
// hell is everyone else doing this? Why isn't
|
|
||||||
// this already in the strings package?
|
|
||||||
func perlChomp(s string) string {
|
|
||||||
// lots of stuff in go moves around the whole block of whatever it is so lots of things are padded with NULL values
|
|
||||||
s = strings.Trim(s, "\x00") // removes NULL (needed!)
|
|
||||||
|
|
||||||
// TODO: christ. make some fucking regex that takes out every NULL, \t, ' ", \n, and \r
|
|
||||||
s = strings.Trim(s, "\n")
|
|
||||||
s = strings.Trim(s, "\n")
|
|
||||||
s = strings.TrimSuffix(s, "\r")
|
|
||||||
s = strings.TrimSuffix(s, "\n")
|
|
||||||
|
|
||||||
s = strings.TrimSpace(s) // this is like 'chomp' in perl
|
|
||||||
s = strings.TrimSuffix(s, "\n") // this is like 'chomp' in perl
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: fix this to chomp \n \r NULL \t and ' '
|
|
||||||
func Chomp(a interface{}) string {
|
|
||||||
// switch reflect.TypeOf(a) {
|
|
||||||
switch t := a.(type) {
|
|
||||||
case string:
|
|
||||||
var s string
|
|
||||||
s = a.(string)
|
|
||||||
return perlChomp(s)
|
|
||||||
case []uint8:
|
|
||||||
// log.Printf("shell.Chomp() FOUND []uint8")
|
|
||||||
var tmp []uint8
|
|
||||||
tmp = a.([]uint8)
|
|
||||||
|
|
||||||
s := string(tmp)
|
|
||||||
return perlChomp(s)
|
|
||||||
case uint64:
|
|
||||||
// log.Printf("shell.Chomp() FOUND []uint64")
|
|
||||||
s := fmt.Sprintf("%d", a.(uint64))
|
|
||||||
return perlChomp(s)
|
|
||||||
case int64:
|
|
||||||
// log.Printf("shell.Chomp() FOUND []int64")
|
|
||||||
s := fmt.Sprintf("%d", a.(int64))
|
|
||||||
return perlChomp(s)
|
|
||||||
case *bytes.Buffer:
|
|
||||||
// log.Printf("shell.Chomp() FOUND *bytes.Buffer")
|
|
||||||
var tmp *bytes.Buffer
|
|
||||||
tmp = a.(*bytes.Buffer)
|
|
||||||
if tmp == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
var bytesSplice []byte
|
|
||||||
bytesSplice = tmp.Bytes()
|
|
||||||
return Chomp(string(bytesSplice))
|
|
||||||
default:
|
|
||||||
tmp := fmt.Sprint("shell.Chomp() NO HANDLER FOR TYPE: %T", a)
|
|
||||||
handleError(fmt.Errorf(tmp), -1)
|
|
||||||
log.Warn("shell.Chomp() NEED TO MAKE CONVERTER FOR type =", reflect.TypeOf(t))
|
|
||||||
}
|
|
||||||
tmp := "shell.Chomp() THIS SHOULD NEVER HAPPEN"
|
|
||||||
handleError(fmt.Errorf(tmp), -1)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is stuff from a long time ago that there must be a replacement for
|
|
||||||
func RemoveFirstElement(slice []string) (string, []string) {
|
|
||||||
if len(slice) == 0 {
|
|
||||||
return "", slice // Return the original slice if it's empty
|
|
||||||
}
|
|
||||||
return slice[0], slice[1:] // Return the slice without the first element
|
|
||||||
}
|
|
|
@ -0,0 +1,192 @@
|
||||||
|
package shell
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-cmd/cmd"
|
||||||
|
"go.wit.com/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// this is a simplified interaction with the excellent
|
||||||
|
// go-cmd/cmd package to work 'shell' like.
|
||||||
|
|
||||||
|
// in all cases here, STDERR -> STDOUT
|
||||||
|
// If you want the output from whatever you run
|
||||||
|
// to be captured like it appears when you see it
|
||||||
|
// on the command line, this is what this tries to do
|
||||||
|
|
||||||
|
/*
|
||||||
|
if r := shell.Run([]{"ping", "-c", "3", "localhost"}); r.Error == nil {
|
||||||
|
if r.Exit == 0 {
|
||||||
|
log.Println("ran ok")
|
||||||
|
} else {
|
||||||
|
log.Println("ran")
|
||||||
|
}
|
||||||
|
// all stdout/stderr captured in r.Stdout
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// shortcut, sends a blank value for pwd
|
||||||
|
// which means the exec Dir is not set
|
||||||
|
// echos output (otherwise use RunQuiet)
|
||||||
|
func Run(args []string) cmd.Status {
|
||||||
|
return PathRun("", args)
|
||||||
|
}
|
||||||
|
|
||||||
|
// exec the cmd at a filepath. this does not change the working directory
|
||||||
|
// sets the exec dir if it's not an empty string
|
||||||
|
// combines stdout and stderr
|
||||||
|
// echo's output (otherwise use PathRunQuiet()
|
||||||
|
// this is basically the exact example from the go-cmd/cmd devs
|
||||||
|
// where the have rocked out a proper smart read on both filehandles
|
||||||
|
// https://dave.cheney.net/2013/04/30/curious-channels
|
||||||
|
func PathRun(path string, args []string) cmd.Status {
|
||||||
|
var save []string // combined stdout & stderr
|
||||||
|
var arg0 string
|
||||||
|
var argx []string
|
||||||
|
// Check if the slice has at least one element (the command name)
|
||||||
|
if len(args) == 0 {
|
||||||
|
var s cmd.Status
|
||||||
|
s.Error = errors.New("Error: Command slice is empty.")
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
if len(args) == 1 {
|
||||||
|
// Pass the first element as the command, and the rest as variadic arguments
|
||||||
|
arg0 = args[0]
|
||||||
|
} else {
|
||||||
|
arg0 = args[0]
|
||||||
|
argx = args[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable output buffering, enable streaming
|
||||||
|
cmdOptions := cmd.Options{
|
||||||
|
Buffered: false,
|
||||||
|
Streaming: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Cmd with options
|
||||||
|
envCmd := cmd.NewCmdOptions(cmdOptions, arg0, argx...)
|
||||||
|
if path != "" {
|
||||||
|
// set the path for exec
|
||||||
|
envCmd.Dir = path
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print STDOUT and STDERR lines streaming from Cmd
|
||||||
|
doneChan := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
defer close(doneChan)
|
||||||
|
// Done when both channels have been closed
|
||||||
|
// https://dave.cheney.net/2013/04/30/curious-channels
|
||||||
|
for envCmd.Stdout != nil || envCmd.Stderr != nil {
|
||||||
|
select {
|
||||||
|
case line, open := <-envCmd.Stdout:
|
||||||
|
if !open {
|
||||||
|
envCmd.Stdout = nil
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
save = append(save, line)
|
||||||
|
fmt.Println(line)
|
||||||
|
case line, open := <-envCmd.Stderr:
|
||||||
|
if !open {
|
||||||
|
envCmd.Stderr = nil
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
save = append(save, line)
|
||||||
|
fmt.Println(line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Run and wait for Cmd to return, discard Status
|
||||||
|
<-envCmd.Start()
|
||||||
|
|
||||||
|
// Wait for goroutine to print everything
|
||||||
|
<-doneChan
|
||||||
|
|
||||||
|
s := envCmd.Status()
|
||||||
|
s.Stdout = save
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// absolutely doesn't echo anything
|
||||||
|
func PathRunQuiet(pwd string, args []string) cmd.Status {
|
||||||
|
// Check if the slice has at least one element (the command name)
|
||||||
|
if len(args) == 0 {
|
||||||
|
var s cmd.Status
|
||||||
|
s.Error = errors.New("Error: Command slice is empty.")
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start a long-running process, capture stdout and stderr
|
||||||
|
a, b := RemoveFirstElement(args)
|
||||||
|
findCmd := cmd.NewCmd(a, b...)
|
||||||
|
if pwd != "" {
|
||||||
|
findCmd.Dir = pwd
|
||||||
|
}
|
||||||
|
statusChan := findCmd.Start() // non-blocking
|
||||||
|
|
||||||
|
ticker := time.NewTicker(2 * time.Second)
|
||||||
|
|
||||||
|
// this is interesting, maybe useful, but wierd, but neat. interesting even
|
||||||
|
// Print last line of stdout every 2s
|
||||||
|
go func() {
|
||||||
|
for range ticker.C {
|
||||||
|
status := findCmd.Status()
|
||||||
|
n := len(status.Stdout)
|
||||||
|
if n != 0 {
|
||||||
|
fmt.Println("todo:removethisecho", status.Stdout[n-1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Stop command after 1 hour
|
||||||
|
go func() {
|
||||||
|
<-time.After(1 * time.Hour)
|
||||||
|
findCmd.Stop()
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Check if command is done
|
||||||
|
select {
|
||||||
|
case finalStatus := <-statusChan:
|
||||||
|
log.Info("finalStatus =", finalStatus.Exit, finalStatus.Error)
|
||||||
|
return finalStatus
|
||||||
|
// done
|
||||||
|
default:
|
||||||
|
// no, still running
|
||||||
|
}
|
||||||
|
|
||||||
|
// Block waiting for command to exit, be stopped, or be killed
|
||||||
|
finalStatus := <-statusChan
|
||||||
|
return finalStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
func blah(cmd []string) {
|
||||||
|
r := Run(cmd)
|
||||||
|
log.Info("cmd =", r.Cmd)
|
||||||
|
log.Info("complete =", r.Complete)
|
||||||
|
log.Info("exit =", r.Exit)
|
||||||
|
log.Info("err =", r.Error)
|
||||||
|
log.Info("len(stdout+stderr) =", len(r.Stdout))
|
||||||
|
}
|
||||||
|
|
||||||
|
// run these to see confirm the sytem behaves as expected
|
||||||
|
func RunTest() {
|
||||||
|
blah([]string{"ping", "-c", "3", "localhost"})
|
||||||
|
blah([]string{"exit", "0"})
|
||||||
|
blah([]string{"exit", "-1"})
|
||||||
|
blah([]string{"true"})
|
||||||
|
blah([]string{"false"})
|
||||||
|
blah([]string{"grep", "root", "/etc/", "/proc/cmdline", "/usr/bin/chmod"})
|
||||||
|
blah([]string{"grep", "root", "/proc/cmdline"})
|
||||||
|
fmt.Sprint("blahdone")
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is stuff from a long time ago that there must be a replacement for
|
||||||
|
func RemoveFirstElement(slice []string) (string, []string) {
|
||||||
|
if len(slice) == 0 {
|
||||||
|
return "", slice // Return the original slice if it's empty
|
||||||
|
}
|
||||||
|
return slice[0], slice[1:] // Return the slice without the first element
|
||||||
|
}
|
31
int.go
31
int.go
|
@ -1,31 +0,0 @@
|
||||||
package shell
|
|
||||||
|
|
||||||
/*
|
|
||||||
send it anything, always get back an int
|
|
||||||
*/
|
|
||||||
|
|
||||||
// import "log"
|
|
||||||
// import "reflect"
|
|
||||||
// import "strings"
|
|
||||||
// import "bytes"
|
|
||||||
import "strconv"
|
|
||||||
|
|
||||||
func Int(s string) int {
|
|
||||||
s = Chomp(s)
|
|
||||||
i, err := strconv.Atoi(s)
|
|
||||||
if err != nil {
|
|
||||||
handleError(err, -1)
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
|
|
||||||
func Int64(s string) int64 {
|
|
||||||
s = Chomp(s)
|
|
||||||
i, err := strconv.Atoi(s)
|
|
||||||
if err != nil {
|
|
||||||
handleError(err, -1)
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return int64(i)
|
|
||||||
}
|
|
|
@ -1,12 +1,12 @@
|
||||||
package shell
|
package shell
|
||||||
|
|
||||||
|
// old code and probably junk
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
)
|
)
|
||||||
|
@ -47,6 +47,7 @@ func Quiet(q bool) {
|
||||||
quiet = q
|
quiet = q
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
func Script(cmds string) int {
|
func Script(cmds string) int {
|
||||||
// split on new lines (while we are at it, handle stupid windows text files
|
// 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")
|
lines := strings.Split(strings.Replace(cmds, "\r\n", "\n", -1), "\n")
|
||||||
|
@ -59,22 +60,7 @@ func Script(cmds string) int {
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
func SpewOn() {
|
|
||||||
spewOn = true
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetDelayInMsec(msecs int) {
|
|
||||||
msecDelay = msecs
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetStdout(newout *os.File) {
|
|
||||||
shellStdout = newout
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetStderr(newerr *os.File) {
|
|
||||||
shellStderr = newerr
|
|
||||||
}
|
|
||||||
|
|
||||||
func Unlink(filename string) bool {
|
func Unlink(filename string) bool {
|
||||||
if err := os.Remove(filename); err != nil {
|
if err := os.Remove(filename); err != nil {
|
||||||
|
@ -84,40 +70,16 @@ func Unlink(filename string) bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func RM(filename string) {
|
|
||||||
os.Remove(Path(filename))
|
|
||||||
}
|
|
||||||
|
|
||||||
func Daemon(cmdline string, timeout time.Duration) int {
|
|
||||||
for {
|
|
||||||
RunString(cmdline)
|
|
||||||
time.Sleep(timeout)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// run something and never return from it
|
|
||||||
// TODO: pass STDOUT, STDERR, STDIN correctly
|
|
||||||
// TODO: figure out how to nohup the process and exit
|
|
||||||
func Exec(cmdline string) {
|
|
||||||
log.Log(INFO, "shell.Run() START "+cmdline)
|
|
||||||
|
|
||||||
cmd := Chomp(cmdline) // this is like 'chomp' in perl
|
|
||||||
cmdArgs := strings.Fields(cmd)
|
|
||||||
|
|
||||||
process := exec.Command(cmdArgs[0], cmdArgs[1:len(cmdArgs)]...)
|
|
||||||
process.Stderr = os.Stderr
|
|
||||||
process.Stdin = os.Stdin
|
|
||||||
process.Stdout = os.Stdout
|
|
||||||
process.Start()
|
|
||||||
err := process.Wait()
|
|
||||||
log.Log(INFO, "shell.Exec() err =", err)
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// run interactively. output from the cmd is in real time
|
// run interactively. output from the cmd is in real time
|
||||||
// shows all the output. For example, 'ping -n localhost'
|
// shows all the output. For example, 'ping -n localhost'
|
||||||
// shows the output like you would expect to see
|
// shows the output like you would expect to see
|
||||||
func NewRun(workingpath string, cmd []string) error {
|
func RunSimple(cmd []string) error {
|
||||||
|
log.Log(INFO, "NewRun() ", cmd)
|
||||||
|
|
||||||
|
return PathRunSimple("", cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func PathRunSimple(workingpath string, cmd []string) error {
|
||||||
log.Log(INFO, "NewRun() ", cmd)
|
log.Log(INFO, "NewRun() ", cmd)
|
||||||
|
|
||||||
process := exec.Command(cmd[0], cmd[1:len(cmd)]...)
|
process := exec.Command(cmd[0], cmd[1:len(cmd)]...)
|
||||||
|
@ -128,10 +90,14 @@ func NewRun(workingpath string, cmd []string) error {
|
||||||
process.Stdout = os.Stdout
|
process.Stdout = os.Stdout
|
||||||
process.Start()
|
process.Start()
|
||||||
err := process.Wait()
|
err := process.Wait()
|
||||||
log.Log(INFO, "shell.Exec() err =", err)
|
if err != nil {
|
||||||
|
log.Log(INFO, "shell.Exec() err =", err)
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return true if the filename exists (cross-platform)
|
||||||
|
|
||||||
// return true if the filename exists (cross-platform)
|
// return true if the filename exists (cross-platform)
|
||||||
func Exists(filename string) bool {
|
func Exists(filename string) bool {
|
||||||
_, err := os.Stat(Path(filename))
|
_, err := os.Stat(Path(filename))
|
||||||
|
@ -175,29 +141,9 @@ func Cat(filename string) string {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return Chomp(buffer)
|
return string(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// run interactively. output from the cmd is in real time
|
|
||||||
// shows all the output. For example, 'ping -n localhost'
|
|
||||||
// shows the output like you would expect to see
|
|
||||||
func RunPathHttpOut(workingpath string, cmd []string, w http.ResponseWriter, r *http.Request) error {
|
|
||||||
log.Log(INFO, "NewRun() ", cmd)
|
|
||||||
|
|
||||||
process := exec.Command(cmd[0], cmd[1:len(cmd)]...)
|
|
||||||
// Set the working directory
|
|
||||||
process.Dir = workingpath
|
|
||||||
process.Stderr = os.Stderr
|
|
||||||
process.Stdin = os.Stdin
|
|
||||||
process.Stdout = os.Stdout
|
|
||||||
process.Start()
|
|
||||||
err := process.Wait()
|
|
||||||
log.Log(INFO, "shell.Exec() err =", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
func RunPathHttpOut(path string, cmd []string, w http.ResponseWriter, r *http.Request) error {
|
func RunPathHttpOut(path string, cmd []string, w http.ResponseWriter, r *http.Request) error {
|
||||||
log.Warn("Run(): ", cmd)
|
log.Warn("Run(): ", cmd)
|
||||||
|
|
253
run.go
253
run.go
|
@ -1,253 +0,0 @@
|
||||||
package shell
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"go.wit.com/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
var msecDelay int = 20 // check every 20 milliseconds
|
|
||||||
|
|
||||||
// TODO: look at https://github.com/go-cmd/cmd/issues/20
|
|
||||||
// use go-cmd instead here?
|
|
||||||
// exiterr.Sys().(syscall.WaitStatus)
|
|
||||||
|
|
||||||
// run command and return it's output
|
|
||||||
/*
|
|
||||||
func RunCapture(cmdline string) string {
|
|
||||||
test := New()
|
|
||||||
test.Exec(cmdline)
|
|
||||||
return Chomp(test.Buffer)
|
|
||||||
}
|
|
||||||
|
|
||||||
func RunWait(args []string) *OldShell {
|
|
||||||
test := New()
|
|
||||||
cmdline := strings.Join(args, " ")
|
|
||||||
test.Exec(cmdline)
|
|
||||||
return test
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// var newfile *shell.File
|
|
||||||
func RunString(args string) bool {
|
|
||||||
// return false
|
|
||||||
parts := strings.Split(args, " ")
|
|
||||||
return Run(parts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Run(args []string) bool {
|
|
||||||
dir, err := os.Getwd()
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
r := RunPath(dir, args)
|
|
||||||
if r.Ok {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
var ErrorArgvEmpty error = errors.New("command was empty")
|
|
||||||
|
|
||||||
type RunResult struct {
|
|
||||||
Ok bool
|
|
||||||
Argv []string
|
|
||||||
Path string
|
|
||||||
Output []byte
|
|
||||||
Err error
|
|
||||||
Outerr error
|
|
||||||
}
|
|
||||||
|
|
||||||
// run, but set the working path
|
|
||||||
func RunPath(path string, args []string) *RunResult {
|
|
||||||
r := new(RunResult)
|
|
||||||
r.Path = path
|
|
||||||
r.Argv = args
|
|
||||||
if len(args) == 0 {
|
|
||||||
r.Ok = true
|
|
||||||
r.Err = ErrorArgvEmpty
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
if args[0] == "" {
|
|
||||||
r.Ok = false
|
|
||||||
r.Err = ErrorArgvEmpty
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
thing := args[0]
|
|
||||||
parts := args[1:]
|
|
||||||
cmd := exec.Command(thing, parts...)
|
|
||||||
cmd.Dir = path
|
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
|
|
||||||
log.Info("path =", path, "cmd =", strings.Join(args, " "))
|
|
||||||
if err := cmd.Run(); err != nil {
|
|
||||||
// Handle error if the command execution fails
|
|
||||||
// log.Info("RunPath() failed")
|
|
||||||
// log.Info("cmd.Enviorn =", cmd.Environ())
|
|
||||||
out, outerr := cmd.Output()
|
|
||||||
// log.Info("cmd.output =", out)
|
|
||||||
// log.Info("cmd.output err=", outerr)
|
|
||||||
// log.Info("path =", path)
|
|
||||||
// log.Info("args =", args)
|
|
||||||
// log.Info("err =", err.Error())
|
|
||||||
r.Ok = false
|
|
||||||
r.Err = err
|
|
||||||
r.Output = out
|
|
||||||
r.Outerr = outerr
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
out, outerr := cmd.Output()
|
|
||||||
r.Output = out
|
|
||||||
r.Outerr = outerr
|
|
||||||
r.Ok = true
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
// send the path and the command
|
|
||||||
// captures the output so you can not see the command run in real time
|
|
||||||
func RunCmd(workingpath string, parts []string) (error, bool, string) {
|
|
||||||
if len(parts) == 0 {
|
|
||||||
log.Warn("command line was empty")
|
|
||||||
return errors.New("empty"), false, ""
|
|
||||||
}
|
|
||||||
if parts[0] == "" {
|
|
||||||
log.Warn("command line was empty")
|
|
||||||
return errors.New("empty"), false, ""
|
|
||||||
}
|
|
||||||
thing := parts[0]
|
|
||||||
parts = parts[1:]
|
|
||||||
log.Log(INFO, "working path =", workingpath, "thing =", thing, "cmdline =", parts)
|
|
||||||
|
|
||||||
// Create the command
|
|
||||||
cmd := exec.Command(thing, parts...)
|
|
||||||
|
|
||||||
// Set the working directory
|
|
||||||
cmd.Dir = workingpath
|
|
||||||
|
|
||||||
// Execute the command
|
|
||||||
output, err := cmd.CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
if thing == "git" {
|
|
||||||
log.Log(INFO, "git ERROR. maybe okay", workingpath, "thing =", thing, "cmdline =", parts)
|
|
||||||
log.Log(INFO, "git ERROR. maybe okay err =", err)
|
|
||||||
if err.Error() == "exit status 1" {
|
|
||||||
log.Log(INFO, "git ERROR. normal exit status 1")
|
|
||||||
if parts[0] == "diff-index" {
|
|
||||||
log.Log(INFO, "git normal diff-index when repo dirty")
|
|
||||||
return nil, false, "git diff-index exit status 1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Warn("ERROR working path =", workingpath, "thing =", thing, "cmdline =", parts)
|
|
||||||
log.Warn("ERROR working path =", workingpath, "thing =", thing, "cmdline =", parts)
|
|
||||||
log.Warn("ERROR working path =", workingpath, "thing =", thing, "cmdline =", parts)
|
|
||||||
log.Error(err)
|
|
||||||
log.Warn("output was", string(output))
|
|
||||||
log.Warn("cmd exited with error", err)
|
|
||||||
// panic("fucknuts")
|
|
||||||
|
|
||||||
// The command failed (non-zero exit status)
|
|
||||||
if exitErr, ok := err.(*exec.ExitError); ok {
|
|
||||||
// Assert that it is an exec.ExitError and get the exit code
|
|
||||||
if status, ok := exitErr.Sys().(syscall.WaitStatus); ok {
|
|
||||||
log.Warn("Exit Status: %d\n", status.ExitStatus())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.Warn("cmd.Run() failed with %s\n", err)
|
|
||||||
}
|
|
||||||
return err, false, string(output)
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp := string(output)
|
|
||||||
tmp = strings.TrimSpace(tmp)
|
|
||||||
|
|
||||||
// Print the output
|
|
||||||
return nil, true, tmp
|
|
||||||
}
|
|
||||||
|
|
||||||
// send the path and the command
|
|
||||||
// also does not seem to show the output in realtime
|
|
||||||
func RunCmdRun(workingpath string, parts []string) error {
|
|
||||||
if len(parts) == 0 {
|
|
||||||
log.Warn("command line was empty")
|
|
||||||
return errors.New("empty")
|
|
||||||
}
|
|
||||||
if parts[0] == "" {
|
|
||||||
log.Warn("command line was empty")
|
|
||||||
return errors.New("empty")
|
|
||||||
}
|
|
||||||
thing := parts[0]
|
|
||||||
parts = parts[1:]
|
|
||||||
log.Log(INFO, "working path =", workingpath, "thing =", thing, "cmdline =", parts)
|
|
||||||
|
|
||||||
// Create the command
|
|
||||||
cmd := exec.Command(thing, parts...)
|
|
||||||
|
|
||||||
// Set the working directory
|
|
||||||
cmd.Dir = workingpath
|
|
||||||
|
|
||||||
// Execute the command
|
|
||||||
err := cmd.Run()
|
|
||||||
if err != nil {
|
|
||||||
log.Warn("ERROR working path =", workingpath, "thing =", thing, "cmdline =", parts)
|
|
||||||
log.Error(err)
|
|
||||||
log.Warn("cmd exited with error", err)
|
|
||||||
// panic("fucknuts")
|
|
||||||
|
|
||||||
// The command failed (non-zero exit status)
|
|
||||||
if exitErr, ok := err.(*exec.ExitError); ok {
|
|
||||||
// Assert that it is an exec.ExitError and get the exit code
|
|
||||||
if status, ok := exitErr.Sys().(syscall.WaitStatus); ok {
|
|
||||||
log.Warn("Exit Status: %d\n", status.ExitStatus())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.Warn("cmd.Run() failed with %s\n", err)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *RunResult) Stdout() string {
|
|
||||||
return string(r.Output)
|
|
||||||
}
|
|
||||||
|
|
||||||
// run, but set the working path
|
|
||||||
func Output(path string, args []string) *RunResult {
|
|
||||||
r := new(RunResult)
|
|
||||||
r.Path = path
|
|
||||||
r.Argv = args
|
|
||||||
if len(args) == 0 {
|
|
||||||
r.Ok = true
|
|
||||||
r.Err = ErrorArgvEmpty
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
if args[0] == "" {
|
|
||||||
r.Ok = false
|
|
||||||
r.Err = ErrorArgvEmpty
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
thing := args[0]
|
|
||||||
parts := args[1:]
|
|
||||||
cmd := exec.Command(thing, parts...)
|
|
||||||
cmd.Dir = path
|
|
||||||
output, err := cmd.CombinedOutput()
|
|
||||||
|
|
||||||
if err := cmd.Run(); err != nil {
|
|
||||||
r.Ok = false
|
|
||||||
r.Err = err
|
|
||||||
r.Output = output
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
r.Output = output
|
|
||||||
r.Err = err
|
|
||||||
r.Ok = true
|
|
||||||
return r
|
|
||||||
}
|
|
3
wget.go
3
wget.go
|
@ -74,8 +74,7 @@ func WgetToFile(filepath string, url string) error {
|
||||||
// BUGS: The author's idea of friendly may differ to that of many other people.
|
// BUGS: The author's idea of friendly may differ to that of many other people.
|
||||||
func Write(filepath string, data string) bool {
|
func Write(filepath string, data string) bool {
|
||||||
// TODO: this isn't working for some reason and is making two '\n' chars
|
// TODO: this isn't working for some reason and is making two '\n' chars
|
||||||
// probably because Chomp() isn't fixed yet
|
data = strings.TrimSpace(data) + "\n"
|
||||||
data = Chomp(data) + "\n"
|
|
||||||
// Create the file
|
// Create the file
|
||||||
ospath := Path(filepath)
|
ospath := Path(filepath)
|
||||||
log.Log(INFO, "shell.Write() START ospath =", ospath, "filepath =", filepath)
|
log.Log(INFO, "shell.Write() START ospath =", ospath, "filepath =", filepath)
|
||||||
|
|
4
xterm.go
4
xterm.go
|
@ -123,7 +123,7 @@ func XtermCmdWait(path string, cmd []string) {
|
||||||
// keeps git diff from exiting on small diffs
|
// keeps git diff from exiting on small diffs
|
||||||
os.Setenv("LESS", "-+F -+X -R")
|
os.Setenv("LESS", "-+F -+X -R")
|
||||||
|
|
||||||
RunCmdRun(path, argsXterm)
|
PathRun(path, argsXterm)
|
||||||
}
|
}
|
||||||
|
|
||||||
// spawns an xterm with something you can run at a command line
|
// spawns an xterm with something you can run at a command line
|
||||||
|
@ -136,5 +136,5 @@ func XtermCmdBash(path string, cmd []string) {
|
||||||
bash += "'; bash\""
|
bash += "'; bash\""
|
||||||
tmp = append(argsXterm, "bash", bash)
|
tmp = append(argsXterm, "bash", bash)
|
||||||
log.Info("XtermCmd() path =", path, "cmd =", tmp)
|
log.Info("XtermCmd() path =", path, "cmd =", tmp)
|
||||||
go RunCmd(path, tmp)
|
go PathRun(path, tmp)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue