title: how to call cancel() when using exec.CommandContext in a goroutine
body: <p>I would like to cancel on demand a running command, for this, I am trying, <a href="https://golang.org/pkg/os/exec/#CommandContext" rel="noreferrer"><code>exec.CommandContext</code></a>, currently trying this:</p>
  
  <p><a href="https://play.golang.org/p/0JTD9HKvyad" rel="noreferrer">https://play.golang.org/p/0JTD9HKvyad</a></p>
  
  <pre><code>package main
  
  import (
      "context"
      "log"
      "os/exec"
      "time"
  )
  
  func Run(quit chan struct{}) {
      ctx, cancel := context.WithCancel(context.Background())
      cmd := exec.CommandContext(ctx, "sleep", "300")
      err := cmd.Start()
      if err != nil {
          log.Fatal(err)
      }
  
      go func() {
          log.Println("waiting cmd to exit")
          err := cmd.Wait()
          if err != nil {
              log.Println(err)
          }
      }()
  
      go func() {
          select {
          case &lt;-quit:
              log.Println("calling ctx cancel")
              cancel()
          }
      }()
  }
  
  func main() {
      ch := make(chan struct{})
      Run(ch)
      select {
      case &lt;-time.After(3 * time.Second):
          log.Println("closing via ctx")
          ch &lt;- struct{}{}
      }
  }
  </code></pre>
  
  <p>The problem that I am facing is that the <code>cancel()</code> is called but the process is not being killed, my guess is that the main thread exit first and don't wait for the <code>cancel()</code> to properly terminate the command, mainly because If I use a <code>time.Sleep(time.Second)</code> at the end of the <code>main</code> function it exits/kills the running command.</p>
  
  <p>Any idea about how could I <code>wait</code> to ensure that the command has been killed before exiting not using a <code>sleep</code>? could the <code>cancel()</code> be used in a channel after successfully has killed the command?</p>
  
  <p>In a try to use a single goroutine I tried with this: <a href="https://play.golang.org/p/r7IuEtSM-gL" rel="noreferrer">https://play.golang.org/p/r7IuEtSM-gL</a> but the <code>cmd.Wait()</code> seems to be blocking all the time the <code>select</code> and was not available to call the <code>cancel()</code></p>