Created
May 27, 2016 18:47
-
-
Save scottcagno/7f7f372429c03b2fd404726084eacf3e to your computer and use it in GitHub Desktop.
Golang exec.Command Timeout Wrapper
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 | |
import ( | |
"bytes" | |
"fmt" | |
"os/exec" | |
"time" | |
) | |
func run(timeout int, command string, args ...string) string { | |
// instantiate new command | |
cmd := exec.Command(command, args...) | |
// get pipe to standard output | |
stdout, err := cmd.StdoutPipe() | |
if err != nil { | |
return "cmd.StdoutPipe() error: " + err.Error() | |
} | |
// start process via command | |
if err := cmd.Start(); err != nil { | |
return "cmd.Start() error: " + err.Error() | |
} | |
// setup a buffer to capture standard output | |
var buf bytes.Buffer | |
// create a channel to capture any errors from wait | |
done := make(chan error) | |
go func() { | |
if _, err := buf.ReadFrom(stdout); err != nil { | |
panic("buf.Read(stdout) error: " + err.Error()) | |
} | |
done <- cmd.Wait() | |
}() | |
// block on select, and switch based on actions received | |
select { | |
case <-time.After(time.Duration(timeout) * time.Second): | |
if err := cmd.Process.Kill(); err != nil { | |
return "failed to kill: " + err.Error() | |
} | |
return "timeout reached, process killed" | |
case err := <-done: | |
if err != nil { | |
close(done) | |
return "process done, with error: " + err.Error() | |
} | |
return "process completed: " + buf.String() | |
} | |
return "" | |
} | |
func main() { | |
s := run(5, "ping", "-c25", "8.8.8.8") | |
fmt.Printf("output: %s\n", s) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
There are better/nicer ways to do this. For instance take a look at:
https://medium.com/@vCabbage/go-timeout-commands-with-os-exec-commandcontext-ba0c861ed738