Skip to content

Instantly share code, notes, and snippets.

@viveksyngh
Created August 28, 2018 14:22
Show Gist options
  • Save viveksyngh/87221bf44b2b37b0d667c644655fb10d to your computer and use it in GitHub Desktop.
Save viveksyngh/87221bf44b2b37b0d667c644655fb10d to your computer and use it in GitHub Desktop.
package main
import (
"bytes"
"context"
"errors"
"fmt"
"log"
"os/exec"
"time"
)
func main() {
fmt.Println("Hello World!!")
command := "ping -c 2 -i 1 8.8.8.8"
out, err := CommandTimeoutWithTimer(command, 2*time.Second)
fmt.Println("Output: ", out)
if err != nil {
fmt.Println("Error:", err.Error())
}
}
//CommandTimeoutWithChannel command timeout using channel and goroutine
func CommandTimeoutWithChannel(command string, timeout time.Duration) (string, error) {
cmd := exec.Command("/bin/bash", "-c", command)
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Start()
if err != nil {
log.Printf("Error : %s", err.Error())
return err.Error(), err
}
done := make(chan error)
go func() { done <- cmd.Wait() }()
timer := time.After(timeout)
select {
case <-timer:
cmd.Process.Kill()
fmt.Println("Command timed out")
return "Command timed out", errors.New("Command Timeout")
case err := <-done:
if err != nil {
return err.Error(), err
}
return out.String(), nil
}
}
//CommandTimeoutWithContext command timeout with background context
func CommandTimeoutWithContext(command string, timeout time.Duration) (string, error) {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
cmd := exec.CommandContext(ctx, "/bin/bash", "-c", command)
out, err := cmd.CombinedOutput()
if ctx.Err() == context.DeadlineExceeded {
fmt.Println("Command timed out")
return "Command timed out", errors.New("Command Timeout")
}
if err != nil {
fmt.Println("Error : ", err.Error())
return string(out), err
}
return string(out), nil
}
//CommandTimeoutWithTimer command timeout with timer
func CommandTimeoutWithTimer(command string, timeout time.Duration) (string, error) {
cmd := exec.Command("/bin/bash", "-c", command)
timer := time.AfterFunc(timeout, func() {
cmd.Process.Kill()
})
out, err := cmd.CombinedOutput()
isExpired := timer.Stop()
if isExpired == false {
fmt.Println("Command timed out")
return "Command timed out", errors.New("Command Timeout")
}
if err != nil {
log.Printf("Error : %s", err.Error())
return string(out), err
}
return string(out), nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment