Created
December 21, 2018 11:12
-
-
Save gomisc/70e22bac6c88b73505cce0d7cd97629b to your computer and use it in GitHub Desktop.
Simple example for run subprocess from golang
This file contains hidden or 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
// ExecuteCommand - execute cmd *exec.Cmd with async output from command stderr, stdout | |
// and return combine output as some byte-buffer object | |
// 1st, 2nd writers - always stdout, stderr | |
func ExecuteCommand(cmd *exec.Cmd, writers ...io.Writer) (buff *Buffer, err error) { | |
var wg sync.WaitGroup | |
var outputWriter, errorWriter io.Writer | |
buff = NewBuffer() | |
// Stdout redirect | |
if len(writers) >= 1 { | |
outputWriter = writers[0] | |
} else { | |
outputWriter = os.Stdout | |
} | |
// stderr redirect | |
if len(writers) >= 2 { | |
errorWriter = writers[1] | |
} else { | |
errorWriter = os.Stderr | |
} | |
/// get streams pipes | |
stdout, err := cmd.StdoutPipe() | |
if CheckIfError(err, "Can't open command stdout pipe") { return buff, err} | |
stderr, err := cmd.StderrPipe() | |
if CheckIfError(err, "Can't open command stderr pipe") { return buff, err} | |
/// start command | |
err = cmd.Start() | |
if CheckIfError(err, "Command start error") { return buff, err } | |
/// get combine output continuously | |
wg.Add(2) | |
go func() { | |
defer wg.Done() | |
routeCmdOutput(stdout, outputWriter, buff) | |
}() | |
go func() { | |
defer wg.Done() | |
routeCmdOutput(stderr, errorWriter, buff) | |
}() | |
/// waiting output done | |
wg.Wait() | |
/// waiting command done | |
err = cmd.Wait() | |
if CheckIfError(err, "Command return non zero status") { return buff, err } | |
return buff, nil | |
} | |
func Execute(name, path string, arg ...string) error { | |
cmd := exec.Command(name, arg...) | |
cmd.Dir = path | |
_, err := ExecuteCommand(cmd) | |
return err | |
} | |
func routeCmdOutput(r io.Reader, w io.Writer, buffer *Buffer) { | |
buf := make([]byte, 128) | |
buffer = NewBuffer() | |
for { | |
n, err := r.Read(buf) | |
if n > 0 { | |
_, err := fmt.Fprint(w, string(buf[0:n])) | |
CheckIfError(err, "") | |
_, err = buffer.Write(buf[0:n]) | |
CheckIfError(err, "") | |
} | |
if err != nil { break } | |
} | |
return | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment