Created
March 11, 2020 22:45
-
-
Save kjk/2e4acc63f4f67eafc9c9a30776c01a22 to your computer and use it in GitHub Desktop.
show progress and capture example for https://blog.kowalczyk.info/article/wOYk/advanced-command-execution-in-go-with-osexec.html (made with https://codeeval.dev)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
// https://blog.kowalczyk.info/article/wOYk/advanced-command-execution-in-go-with-osexec.html | |
import ( | |
"bytes" | |
"fmt" | |
"io" | |
"log" | |
"os" | |
"os/exec" | |
"runtime" | |
"sync" | |
) | |
// CapturingPassThroughWriter is a writer that remembers | |
// data written to it and passes it to w | |
type CapturingPassThroughWriter struct { | |
buf bytes.Buffer | |
w io.Writer | |
} | |
// NewCapturingPassThroughWriter creates new CapturingPassThroughWriter | |
func NewCapturingPassThroughWriter(w io.Writer) *CapturingPassThroughWriter { | |
return &CapturingPassThroughWriter{ | |
w: w, | |
} | |
} | |
// Write writes data to the writer, returns number of bytes written and an error | |
func (w *CapturingPassThroughWriter) Write(d []byte) (int, error) { | |
w.buf.Write(d) | |
return w.w.Write(d) | |
} | |
// Bytes returns bytes written to the writer | |
func (w *CapturingPassThroughWriter) Bytes() []byte { | |
return w.buf.Bytes() | |
} | |
func main() { | |
cmd := exec.Command("ls", "-lah") | |
if runtime.GOOS == "windows" { | |
cmd = exec.Command("tasklist") | |
} | |
var errStdout, errStderr error | |
stdoutIn, _ := cmd.StdoutPipe() | |
stderrIn, _ := cmd.StderrPipe() | |
stdout := NewCapturingPassThroughWriter(os.Stdout) | |
stderr := NewCapturingPassThroughWriter(os.Stderr) | |
err := cmd.Start() | |
if err != nil { | |
log.Fatalf("cmd.Start() failed with '%s'\n", err) | |
} | |
var wg sync.WaitGroup | |
wg.Add(1) | |
go func() { | |
_, errStdout = io.Copy(stdout, stdoutIn) | |
wg.Done() | |
}() | |
_, errStderr = io.Copy(stderr, stderrIn) | |
wg.Wait() | |
err = cmd.Wait() | |
if err != nil { | |
log.Fatalf("cmd.Run() failed with %s\n", err) | |
} | |
if errStdout != nil || errStderr != nil { | |
log.Fatal("failed to capture stdout or stderr\n") | |
} | |
outStr, errStr := string(stdout.Bytes()), string(stderr.Bytes()) | |
fmt.Printf("\nout:\n%s\nerr:\n%s\n", outStr, errStr) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment